6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

协作翻译

原文:6 magic sugars that can make your Kotlin codebase happier — Part 1

链接:https://medium.com/grand-parade/6-magic-sugars-that-can-make-your-kotlin-codebase-happier-part-1-ceee3c2bc9d3

译者:边城, 凉凉_, Tocy, 亚林瓜子

语法糖会导致分号的悲剧。—— Alan J. Perlis

我们不断地失去一些东西。其中一些东西相对来说会更重要,现在重新拣起来还不算太晚。Kotlin 语言为程序带员的生活带来了大量新的概念和特性,它们在日常开发中使用起来会很困难。我在生产环境中使用了两年 Kotlin 之后,才感受到它带来的快乐和满足。这是怎么发生的?原因就在那些小小的语法糖中。

我会在本文中与你分析我最喜欢的 Kotlin 语法糖,它们是在我需要写简洁而鲁棒 Android 应用程序组件时发现的。为了让这篇文章读起来更轻松,我把它分成三个部分。在这第一部分中,你会看到密封类和 when() 控制流函数。愉快的开始吧!

拥抱“模式匹配”的密封类

最近我的工作中有机会使用 Swift。我不仅要审核代码,还要将其中一些组件翻译成 Kotlin 实现。我读的代码越多,就越感到惊讶。最对我来说,最吸引人的特性是枚举。可惜 Kotlin 的枚举并不太灵活,我不得不挖掘合适的替代品:密封类。

密封类在编程界并不是什么新鲜玩意儿。事实上,密封类是一个非常知名的语言概念。Kotlin 引入了 sealed 关键字,它可用于类声明,表示对类层次结构的限制。某个值可以是有限类型中的一个,但它不能是其它类型。简单地说,你可以使用密封类来代替枚举,甚至做更多事情。

来看看下面的示例代码。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

乍一看,这些代码除只是声明了一些简单的继承关系,但步步深入,就会提示一个谅人的真相。为 Response 类添加的 sealed 关键字到底起到了什么作用呢?提示这个问题最好的方法是使用 IntelliJ IDEA Kotlin Bytecode 工具。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

第 1 步。查看 Kotlin 字节码 (Kotlin Bytecode)

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

第 2 步。将 Kotlin 字节码反编译成 Java 代码

经过这样非常简单地翻译,你可以看到 Kotlin 代码对应的 Java 代码呈现。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

你可能已经猜到了,密封类专们用于继承,所以它们是抽象的。不过他们变得与枚举相似的?在这里,Kotlin 编译器做了大量的工作,让你可以在 when() 函数中将 Response 的子类用作分支。此外,Kotlin 提供了很大的灵活性来允许对密封类的继承结构可以被当作数据声明甚至对象来使用。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

它不仅提供了非常彻底的表达式,还提供了自动类型转换,因此你可以在不需要额外的转换的情况下使用 Response 实例。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

你能想象一下,如果没有一个 sealed 的功能,或者根本没有 Kotlin ,它可能看起来是那么的丑陋和复杂?如果你忘记了 Java 语言的一些特性,请再次使用 IntelliJ IDEA Kotlin Bytecode ,但要坐下来使用 - 这可能会让你晕倒。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

总结一下,我很高兴在这种情况下使用 sealed 关键字,因为它让我以类似于 Swift 的方式塑造我的 Kotlin 代码。

使用 when()函数来排列

由于你已经看到了 when()在 sealed 类中的用法,我决定再分享更多强大的功能。 想象一下,你必须实现一个接受两个 enums 并产生一个不可变状态的函数。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

enum class Employee 描述了在公司 XYZ 中可以找到的所有角色, enum class Contract 包含所有类型的雇佣合同。 基于这两个 enums ,你应该返回一个正确的 SafariBookAccess 。 而且,你的函数必须产生给定 enum 的所有排列的状态。 第一步,我们来创建状态生成函数的签名。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

现在是时候定义 SafariBooksAccess 结构体了,因为你已了解 sealed 关键字,这是使用它最适合的时机。封装 SafariBookAccess 并不是必须的,但它是封装不同情景下的 SafariBookAccess 的不同状态的好方式。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

那么隐藏在 access() 函数后面的主要意图是什么?全排列!让我们罗列下。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

这个代码很完美,但你能让它更像 Kotlin 吗?当你每天对同事的 PR/MR 进行审查时会有什么建议吗?你可能会写一些这样的评论:

  • 太多 when() 函数。使用 Pair 来避免嵌套。
  • 改变枚举参数的顺序,定义 Pair<Contract, Employee>() 对象来让它更易读。
  • 合并重复的 return。
  • 改为一个表达式函数。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

现在它看起来更整洁,但 Kotlin 还有语法糖可以完全省略对 Pair 的定义。棒!

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

这个结构让我的生活变得轻松,也让 Kotlin 代码读写变得容易,我希望你也觉得这很有用。但它是不是不能用于三元组呢?答案是肯定的。

6个能让你的 Kotlin 代码库更有意思的“魔法糖”(第一部分)

以上就是第 1 部分的全部内容,如果你仍然很有兴趣,请关注第 2 部分,后续我们会更新。

上一篇:使用vue-route下的next({ ...to, replace: true })报Redirected when going from “/login“ to “/home“ via a nav


下一篇:Laravel5版本在sql查询时用when方便条件判断查询【闭包方式】