Kotlin初学须知
写在前面
根据 郭霖的《第一行代码》总结,主要用于 Java 转 Kotlin
(幸运地拿到了第一批的签名版~
麻了,有 Kotlin 中文站,此文仅做个人理解
变量与函数
val
(value)不可变、var
(variable)可变,Kotlin
能类型推导,尽可能用 val
1 | fun methodName(p1: Int, p2: Int): Int { |
函数语法糖:
1 | fun methodName(p1: Int, p2: Int): Int = max(p1, p2) |
逻辑控制
when
类似 switch
,还支持 类型匹配(is Int -> println("...")
)
1 | fun getScore(name: String) = when { |
val range = 0..10
即 [0,10]
val range = 0 until 10
即 [0,10)
for-in
循环:
1 | for(i in 0..10) { |
类与对象
默认都是 final
,需要此类能被继承需要在类名前面添加 open
关键字:
1 | open class Person { ... } |
只能有一个主构造函数,但可以有多个次构造函数,但次构造函数 constructor
必须 间接调用 主构造函数 this
:
1 | class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { |
密封类
sealed
when
时可以用到,不用写 else
数据类与单例类
data
关键字直接帮你把 equals()
、hashCode()
、toString()
等方法都自动生成:
1 | data class YourClass(val p1: String, val p2: Int) |
object
替换 class
:
1 | object MySingleton { |
泛型
语法和 Java
一样
Kotlin
特性:
1 | // 类型推导 |
out
与 in
:声明处型变
类型擦除
函数可见性修饰符
修饰符 | Java(4种) | Kotlin(4种) |
---|---|---|
public | 所有类可见 | 所有类可见(默认) |
private | 当前类可见 | 当前类可见 |
protected | 当前类、子类、同一包路径下的类可见 | 当前类、子类可见 |
default | 同一包路径下的类可见(默认) | 无 |
internal | 无 | 同一模块中的类可见 |
Kotlin奇奇怪怪的函数
listOf
初始化集合(不可变):
1 | val list = listOf("A", "B") |
mutableListOf
初始化集合(可变):
1 | val list = mutableListOf("A", "B") |
Set
和 List
一样 → setOf
和 mutableSetOf
对于 Map
,Kotlin
不推荐用 put
、get
来操作,而是用下标:
1 | // to 不是关键字,而是 infix 函数 |
高阶函数
参数或返回值类型是函数的函数就是高阶函数
例如:
1 | fun example(func: (String, Int) -> Unit) { // Unit是妹有返回值 |
对高阶函数的调用:
1 | fun main() { |
高阶的背后原理还是匿名类调用,即调用 Function
接口产生的匿名类实例的 invoke
方法。
内联函数
而 内联函数
能够解决高阶函数产生的开销,能直接替换代码
1 | inline fun test1(p1: String, p2: Int, func: (String, Int) -> Unit) { |
而 noinline
关键字这是让此参数不要内联:
1 | inline fun test1(noinline func1: (String, Int) -> Unit, func2: (String, Int) -> Unit) { |
内联函数的缺点是:无法将函数作为参数去传递,只允许传递给另一个内联函数
tips:内联函数能直接在 Lambda
中 return
,且返回的是外层的函数:
1 | // 内联 |
郭霖:“将高阶函数声明成内联函数是一种良好的编程习惯”
tips:在内联函数中创建另外的
Lambda
或匿名类实现,并在其中调用函数参数,会报错原因:在另外的
Lambda
或匿名类实现中无法return
解决:用
crossinline
修饰函数参数,保证不会用return
…
标准函数
with、run、apply
定义静态方法
1 | class Util { fun doAction1() { println("do action1") } |
扩展函数
类名.扩展函数
运算符重载
协程
GlobalScope.launch
函数、delay()
函数、runBlocking
函数、launch
函数(子协程)、suspend
关键字、coroutineScope
函数(coroutine:协程)、
1 | val job = Job() |
async
函数和 await
withContext
函数
suspendCoroutine
函数
待更新…
companion object
、@JvmStatic
、顶层方法、as
、lateinit
、sealed class
、扩展函数、运算符重载、为什么取消checked exception
、泛型上界Any?和Any
、类委托(by
)和委托属性(by
)、懒加载by lazy {...}
就是委托属性、A to B
即A.to(B)
、infix
、泛型实化(reified
)、- 编译时判空、人为为空、判空辅助
?.
、?:
、!!
- 标准函数
let
、with
、run
、apply
、repeat