#31 天学习 Kotlin — 第一周回顾
我们写的 Kotlin 代码越多,我们越喜欢她!Kotlin 的现代语言特性和 Android KTX 使我们的 Android 代码更加的简洁,清晰和优雅。我们 (@FMuntenescu 和 @objcode)启动了 #31DaysOfKotlin 系列作为分享我们最喜爱的 Kotlin 和 Android KTX 特性的一种方式,希望你和我们一样,越来越喜欢她。
在前 7 天的时间里,我们专注于基础知识。
Day 1: Elvis 操作符
需要处理代码中的空值?可以使用 elvis 操作符,避免您的 “空情况” (null-erplate)。这只是替换空作为值或者返回事件情况的一个小语法。文档: Elvis operator.
1 | val name: String = person.name ?: “unknown” |
Day 2: 字符串模板
格式化字符串?将 $ 符放在变量名的前面表达字符串中的变量和表达式。使用 ${expression} 求表达式的值。文档: string templates.
1 | val language = “Kotlin” |
Day 3: 解构声明
Android KTX 使用解构来指定颜色的组件值。 你可以在类中使用解构,或者扩展现有的类来添加解构。文档: destructuring declarations.
1 | // now with prisms |
Day 4: When 表达式
强大的 switch!Kotlin 的 When 表达式几乎可以匹配任何东西。字面值,枚举,数字范围。您甚至可以调用任意的函数!文档: when
1 | class Train(val cargo: Number?) { |
Day 5: 循环,范围表达式与解构
for 循环在与其他两种 Kotlin 特性一起使用时可以获得超级能力:范围表达式和解构。 文档: ranges, destructuring.
1 | // iterating in the range 1 to 100 |
Day 6: 属性
在 Kotlin 中,类可以具有可变和只读属性,默认情况下生成 getter 和 setter。如果需要,你也可以自定义。文档: properties.
1 | class User { |
Day 7: Data 类 and equality
创建一个处理数据的类?将它们标记为 “Data” 类。并默认实现生成 equals() 方法 - 相当于 hashCode(),toString() 和 copy(),并检查结构是否相等。文档: data classes, equality
1 | data class User( |
本周重点介绍了 Kotlin 的基础:处理空错误,简化循环和条件,改进 getter 和 setter,以及删除样板。 下周我们将深入了解更多 Kotlin 功能!
#31 天学习 Kotlin — 第二周回顾
在第二部分,我们将继续探索 Kotlin - 深入研究密封类和内联等。
Day 8: 可见性
在 Kotlin 中一切都是默认 public 的。并且 Kotlin 还有一套丰富的可见性修饰符,例如:private, protected, internal。它们每个都以不同的方式降低了可见性。 文档: visibility modifiers
1 | // public by default |
Day 9: 默认参数
方法参数的数量是否太多?在函数中指定默认参数值。使用命名参数使代码更具可读性。 文档: default arguments
1 | // parameters with default values |
Day 10: Sealed 类
Kotlin 的 sealed 类可以让你轻松地处理错误数据,当结合 LiveData 时, 你可以用一个 LiveData 同时代表成功和失败的情况,这比用两个变量要好。文档: sealed classes
1 | sealed class NetworkResult |
你也可以将 sealed 类用在 RecyclerView 的 adapter 中。它们非常适合 ViewHolders —— 用一组清晰的类型明确地分派给每个 holder。用作表达式时,如果有类型不匹配,编译器将会报错。
1 | // use Sealed classes as ViewHolders in a RecyclerViewAdapter |
使用 RecyclerViews 时,如果我们有很多来自 RecyclerView 中 item 的回调,比如一个点击,分享和删除 item 的项目,我们也可以使用 sealed 类。一个回调就可以处理所有的事情!
1 | sealed class DetailItemClickEvent |
Day 11: 懒加载
懒加载是个好东西!通过使用懒加载,可以省去昂贵的属性初始化成本,直到它们真正需要。计算值然后保存并为了未来任何时候的调用。文档: lazy
1 | val preference: String by lazy { |
Day 12: Lateinit
Android 中,在 onCreate 或者其它的回调初始化对象,但在 Kotlin 中不为空的对象必须初始化。那么怎么办呢?可以输入 lateinit。来承诺最终将会初始化。拉钩保证它是空安全的。 文档: lateinit
1 | class MyActivity : AppCompatActivity() { |
Day 13: Require 和 check
你方法的参数是有效的吗?用 require 在使用前可以检查它们,如果它们是无效的将会抛出 IllegalArgumentException。文档: require
1 | fun setName(name: String) { |
您的封闭类的状态是否正确?可以使用 check 来验证。如果检查的值为 false,它将抛出 IllegalStateException。文档: check
1 | fun User.logOut(){ |
Day 14: 内联
等不及要使用 lambdas 来生成一个新的接口?kotlin 可以让你定义一个 inline 的方法 – 这意味着调用将替换方法体,用很非常简单的方法来生成 lambda 的接口。文档: inline functions
1 | // define an inline function that takes a function argument |
本周深入研究了 Kotlin 的特性:可见性,默认参数,密封类,懒加载,延迟初始化,require 和 check,以及强大的内联。 下周我们将深入了解更多的 Kotlin 特性并开始探索 Android KTX。
#31 天学习 Kotlin — 第三周回顾
第 3 周分为 Kotlin 特性和使用 Android KTX 使 Android 代码更优雅的几种方式。
Day 15: 操作符重载
用操作符重载可以更快速写 Kotlin。像 Path,Range 或 SpannableStrings 这样的对象允许像加或减这样的操作。通过 Kotlin,你可以实现自己的操作符。 文档: operator overloading, Android KTX usage example.
1 | // Definition |
Day 16: 顶层方法和参数
类的工具方法?将它们添加到源文件的顶层。在 Java 中,它们被编译为该类的静态方法。文档: basic syntax.
1 | // Define a top-level function that creates a DataBinding Adapter for a RecyclerView |
你是否为你的类定义了静态常量?使它们成为顶层属性。它们将被编译为字段和静态访问器。
1 | // Define a top-level property for Room database |
Day 17: 在没有迭代器的情况下迭代类型
迭代器用在了有趣的地方!Android KTX 将迭代器添加到 ViewGroup 和 SparseArray。要定义迭代器扩展请使用 operator 关键字。 Foreach 循环将使用扩展名!文档: for loops, Android KTX usage example.
1 | // Example from Android KTX |
Day 18: 简单的 Content Values
将 ContentValues 的强大功能与 Kotlin 的简洁性相结合。使用 Android KTX 只传递一个 Pair <StringKey,Value> 创建 ContentValues。Android KTX 实现.
1 | val contentValues = contentValuesOf( |
Day 19: DSLs
DSL 可以通过使用类型安全的构建器来完成。它们简化了 API ;你也可以借助extension lambdas 和type safe builders等功能来构建它们。
1 | html { |
Spek 是一个构建为 Kotlin DSL 的测试库。Spek 不使用 @Annotations,而是提供了一种不依赖于反射的类型安全的方式来声明测试代码。
1 |
|
Android 上 Kotlin 的另一个 DSL 是 Anko。Anko 允许您使用声明性代码构建 Android 视图。
1 | frameLayout { |
Day 20: 简单的 Bundle
准备去通过简洁的方式(bundle creator in Android KTX)去创建 bundle,不调用 putString,putInt,或它们的 20 个方法中的任何一个。一次调用让您生成一个新的 Bundle,它甚至可以处理 Arrays!
1 | val bundle = bundleOf( |
Day 21: 简化 postDelayed
Lambdas 非常贴心。使用最后一个参数调用语法您可以取消回调,Callable 和 Runnable. 例如 Android KTX 贴心的用一个小包装来处理 postDelayed。
1 | // Android KTX API |
本周重点介绍了一些基本的 Kotlin 特性,如运算符重载,顶层函数和参数以及迭代器,我们讨论了一个高级功能:领域特定语言(DSL),并展示了使用 Android KTX 如何编写更简洁的代码。content values, bundles 和 callbacks。
#31 天学习 Kotlin — 第四周回顾
第 4 周学习更多的语言基础知识,然后在某方面使用 Android KTX 使您的代码更简洁和可读!
Day 22: 在 Java 语言中调用 Kotlin
在同一个项目中使用 Kotlin 和 Java?你有没有顶层函数或属性的类呢?默认情况下,编译器将生成类名为 YourFileKt 的类。通过使用 @file:JvmName 注释文件来更改它。文档: package level functions
1 | // File: ShapesGenerator.kt |
Day 23: 具体化
具体化概念的一个例子:Android KTX 中的 Context.systemService() 使用泛化通过泛型传递 “真实” 类型。没有通过 getSystemService。文档: reified type parameters Android KTX: Context.systemService()
1 | // the old way |
Day 24: Delegates
通过 by 把你的工作委托给另一个类。通过类继承,并将属性访问器逻辑与委托者属性重用。 文档: delegation and delegated properties
1 | class MyAnimatingView : View( /* … */ ) { |
Day 25: 扩展函数
没有更多的 Util 类。通过扩展函数来扩展类的功能。把你要扩展的类的名字放在你添加的方法的名字前面。 文档: extension functions
扩展功能的一些特性:
不是成员函数
不以任何方式修改原始类
通过静态类型信息解决编译时间
会被编译为静态函数
不是多态
例如: String.toUri()
1 | // Extend String with toUri |
Day 26: Drawable.toBitmap() 轻松转换
如果你曾经将 Drawable 转换为 Bitmap,那么你需要多少样板代码呢?
Android KTX 具有一系列功能,可以使您的代码在使用 graphics 包中类时更加简洁。 文档: graphics
1 | // get a drawable from resources |
Day 27: Sequences, lazy 和 generators
序列是从未存在的列表。序列是迭代器的表亲,一次只能懒散地产生一个值。这在使用 map 和 fifter 时非常重要 - 它们将创建序列,而不是为每一步都复制列表!文档: sequences
1 | val sequence = List(50) { it * 5 }.asSequence() |
你可以从列表中创建序列或指定下一个功能。如果您永远不会终止一个序列,它可以是无限长的而不会耗尽内存。使用 Kotlin 中的协程也可以用生成器! 文档: generators
1 | // make a sequence from a list |
Day 28: 更简单的 spans
功能强大但是很难使用 - 这就是 text styel Spans API 给人的感觉。 Android KTX 为一些最常见的 span 添加了扩展功能,并使 API 更易于使用。Android KTX: spannable string builder
1 | val string = buildSpannedString { |
Day 29: Parcelize
喜欢 Parcelable 的速度,但不喜欢写所有的代码?和 @Parcelize 打个招呼吧。Spec: Parcelize
1 |
|
Day 30: updatePadding 扩展
通过默认参数扩展现有的 API 通常会让人感到高兴。 Android KTX 允许你使用默认参数在 View 的一侧设置 Padding。一个函数可以节省很多代码! Android KTX: View.updatePadding
1 | view.updatePadding(left = newPadding) |
Day 31: 范围外 run, let, with, apply
让我们运行一些标准的 Kotlin 函数!简短而强大,run,let,with 和 appy 都有一个接收器 (this),可能有一个参数 (it) 并可能有一个返回值。差异如下:
run
1 | val string = “a” |
let
1 | val string = “a” |
with
1 | val string = “a” |
apply
1 | val string = “a” |
本周介绍了一些语言特性,例如 interop,refied 和 sequence,然后我们转向 Android KTX,展示了它帮助你编写简洁易读的代码的一些方法。 为了完成这个系列,我们介绍了功能强大的 Kotlin scope 函数。