开始
对一个对象实例调用多个方法(使用 with)
1 | class Turtle { |
配置对象的属性(使用 apply)
1 | val myRectangle = Rectangle().apply { |
类与对象
属性与字段
幕后字段
1 | var counter = 0 // Note: the initializer assigns the backing field directly |
用value
的值指定counter
的值。
幕后属性
1 | private var _table: Map<String, Int>? = null |
可见性修饰符
类、对象、接口、构造函数、方法、属性和它们的 setter 都可以有可见性修饰符(getter 与属性有相同的可见性)。
Kotlin 中有 private
protected
internal
public
四个可见性修饰符,默认是public
。
internal
模块内可见。
注意:Kotlin 中,外部类不能访问到内部类的private
成员。
对象声明
即一个关键字object
实现单例。
伴生对象
用companion
关键字声明伴生对象,即类内部的对象。
1 | class MyClass { |
委托
1 | interface Base { |
可以看到Derived
类相比普通的声明多了by b
这部分,这部分的意思就是说把b
的公有成员都委托给Derived
。
委托属性
标准委托
Kotlin 标准库中内置了几种委托。
延迟属性 Lazy
lazy()
接受一个 lambda 并返回一个Lazy<T>
的实例,返回的实例作为延迟属性的委托。第一次调用 get()
会执行已传递给 lazy()
的 lambda 表达式并记录结果, 后续调用 get()
只返回记录的结果。
可观察属性 Observable
1 | import kotlin.properties.Delegates |
Delegates.observable()
接受两个参数初始值inintalValue
和值改变时的回调方法onChange
,onChange
接受三个参数:被赋值的属性,旧值,新值。在回调方法被调用前,值已经改变过了。
如果需要拦截新值并否决,可以使用vetoable()
代替observable()
,在新值生效前会调用回调方法。
把属性储存在 map 中
1 | class User(val map: Map<String, Any?>) { |
函数
函数可以有默认参数。当覆盖(重写)一个有默认参数的函数时,新函数不可以设置默认值。
当向函数传递参数时,可以指定参数的名称。
函数的可变参数(通常是最后一个)可以用 vararg
修饰符标记。当把一个数组a
传给可变参数,可以用*a
(伸展操作符 Spread )。
中缀表示函数:
1 | infix fun Int.shl(x: Int): Int { …… } |
高阶函数和 Lambda 表达式
高阶函数是将函数用作参数或返回值的函数。
Kotlin 中,如果一个函数的参数的最后一个参数为函数,则这个函数参数可以放在()
外,写在{}
里。更甚,如只有一个参数且为函数,则()
也可省略。
Lambda 表达式或者匿名函数(以及局部函数和对象表达式) 可以访问其 闭包 ,即在外部作用域中声明的变量。 在 lambda 表达式中可以修改闭包中捕获的变量:
1 | var sum = 0 |
内联函数
inline
修饰符会影响函数本身和传给它的 lambda 表达式,它们被内联到调用处,可以提高一些效率。
1 | inline fun <T> lock(lock: Lock, body: () -> T): T { …… } |
1 | lock(l) { foo() } |
1 | l.lock() |
扩展函数
1 | fun MutableList<Int>.swap(index1: Int, index2: Int) { |
1 | val list = mutableListOf(1, 2, 3) |
作用域函数
函数 | 对象引用 | 返回值 | 是否是扩展函数 |
---|---|---|---|
let |
it |
Lambda 表达式结果 | 是 |
run |
this |
Lambda 表达式结果 | 是 |
run |
- | Lambda 表达式结果 | 不是:调用无需上下文对象 |
with |
this |
Lambda 表达式结果 | 不是:把上下文对象当做参数 |
apply |
this |
上下文对象 | 是 |
also |
it |
上下文对象 | 是 |
协程
参考
待
2020-3-17 23:50:39