Kotlin拾遗
return
关键字
从封闭函数中返回
1 | fun lookForAlice(people: List<Person>) { |
用标签返回
1 | people.forEach { |
函数名作为标签返回
1 | people.forEach { |
匿名函数局部返回
1 | people.forEach(fun(person) { |
面向对象
所有类默认为final
open
主/次构造函数
类可以有一个主构造函数和多个次构造函数
1 | class User(name: String) { // 此处实际上省略了 |
扩展函数
扩展函数不可以重写
。
1 | fun Int.isEven() = this % 2 == 0 |
伴生对象
可以为伴生对象命名
1 | companion object Loader { ... } |
为匿名伴生对象定义扩展函数时Companion
1 | fun ClsName.Companion.getSomething(): Type { ... } |
枚举类
软关键字
如此处的enum
class
1 | enum class Color(rgb: Int) { |
下例获取枚举类常量的个数
1 | val n = enumValues<EnumClsName>().size |
enumValues<T>()
返回一个 Array<T>
使可以通过泛型数组的形式访问枚举类的常量 , 。
数据类
自动创建属性
1 | data class User(var id: Int, var name: String) |
自定义运算符
等式校验
Kotlina==b
a?.equals(b)?:(b == null)
a===b
1 | override fun equals(obj: Any?): Boolean { |
equals()
Any
!=
也会转换为equals()
的调用 。
排序校验
要实现Comparable
>
<
>=
和<=
1 | class Person(...): Comparable<Person> { |
其他
1 | operator fun plus(other: Cls): Cls { ... } |
函数
高阶函数
函数的参数或返回值类型也为函数
1 | fun String.filter(predicate: (Char) -> Boolean): String { |
闭包
当函数最末参数为
例如Thread
1 | Thread(object : Runnable { |
SAM(Single Abstract Method)
单抽象方法
满足
1 | Thread({ ... }) |
使用闭包还可简化为如下
1 | Thread { ... } |
形如
Thread { ... }
的结构中, {}
就是一个闭包。
函数引用
1 | val fRef = ::f |
可以
fRef(params)
其本质是 , fRef.invoke(params)
。
返回值可空的函数类型
1 | var canReturnNull: (Int, Int) -> Int? = { null } |
函数类型的可空变量
1 | var funOrNull: ((Int, Int) -> Int)? = null |
空安全
?.
空安全调用运算符
foo?.bar()
- 当
foo!=null
得到, foo.bar()
; - 当
foo==null
得到, null
。
?:
空值合并运算符
又称
Elvis 运算符 顺时针旋转 。 90° 看起来像猫王 , Elvis 一样 。
foo?:bar()
- 当
foo!=null
得到, foo
; - 当
foo==null
得到, bar
。
as?
安全转换
foo as? Type
- 当
foo is Type
得到, foo as Type
; - 当
foo !is Type
得到, null
。
?:
和 as?
可结合使用 : b as? A ?: Type
。
!!
非空断言
一旦使用
!!
空安全优势便不得体现 , 。
foo!!
- 当
foo!=null
得到, foo
; - 当
foo==null
得到, NullPointerException
。
泛型
擦除
ERROR:
Cannot check for instance of erased type: T
.
1 | fun<T> isA(value: Any) = value is T // ERROR! |
实化
1 | inline fun<reified T> isA(value: Any) = value is T |
通配
1 | if(value is List<*>) { ... } |
上界约束
1 | fun<T: Number> oneHalf(value: T): Double { |
多重约束
1 | fun<T> ensureTrailingPeriod(seq: T) |
非空约束
1 | class Processor<T: Any> { ... } |
默认的
<T>
使T
的类型可空。
协变
1 | interface List<out T> { fun getSomething(index: Int): T } |
逆变
1 | interface Compare<in T> { fun compare(first: T, second: T): Int } |
多线程
协程 (Coroutine)
一套线程
下例的调度器
(Dispatchers) 可将协程限制于特性线程执行 或将它分配至一个线程池 , 或让它不受限制地运行 , 。
1 | launch(Dispatchers.Main) { // 在 |
非阻塞式挂起
非阻塞
协程的写法看似阻塞
挂起
稍后会自动切回的线程切换
自定义挂起函数而未调用挂起函数withContext()
)suspend
关键字
suspend
仅是标识提醒的作用 与挂起的实现无关 , 。
1 | suspend fun getInfo() = withContext(Dispatchers.IO) { |