Kotlin
prons:
语法糖
Null Safety
函数式编程
代数类型
不可变对象
#1
kotlin中class没有静态方法/类属性,定义companion object,作为一个放置工厂函数和静态成员的地方,同时能够访问class其他方法和属性
鼓励在一个source文件中定义多个相关的class,fun
#2 Porperties and Fields
Backing Fields
用于在getter/setter函数中引用propertie对象,backing field的作用域仅仅存在于当前属性的setter/getter方法中。避免在setter/getter方法中对属性进行赋值时产生第归调用。
var counter = 0 // Note: the initializer assigns the backing field directly
set(value) {
if (value >= 0) field = value
}
Backing properties
显式声明backing field,对外表现为 val 属性,只能读不能写;在类内部表现为 var 属性,也就是说只能在类内部改变它的值。
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
get() {
if (_table == null) {
_table = HashMap() // Type parameters are inferred
}
return _table ?: throw AssertionError("Set to null by another thread")
}
#3 Extensions
extension method
扩展类的方法,相当于给一个类添加静态方法。(缺点是存在这么一种情况,不同的类库在同一个类上实现了同名的扩展方法,在使用时需要额外小心)
extension method是由调用者的声明对象决定的。
extension properties
扩展属性不能直接初始化。因为扩展并没有真的在类中加入成员,扩展属性没有backing field。
#4 sealed class
abstract类,用来表示受限的类继承关系
相当于enum的扩展,sealed class可以有多个子类。
fun eval(expr: Expr): Double = when(expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}
#delegation
class Derived(b: Base) : Base by b
声明将Base类型的b保存在Derived类的对象中,并且把Base类的所有方法定向到b对象
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { print(x) }
}
class Derived(b: Base) : Base by b
fun main() {
val baseImpl = BaseImpl(10)
Derived(baseImpl).print()
}
#higher-order functions
可以以funs作为参数/返回值的fun
#inline function
调用一个方法是一个压栈和出栈的过程,调用方法时将栈针压入方法栈,然后执行方法体,方法结束时将栈针出栈,这个压栈和出栈的过程会耗费资源,这个过程中传递形参也会耗费资源。
使用inline函数(编译时期展开函数),建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。
https://blog.csdn.net/Jaden_hool/article/details/78437947
#type-safe builder
kotlin DSL, 重用代码并创建抽象
利用带有接收者的lambda表达式实现type-safe builder
#函数式编程
更高层次的抽象,可以将函数作为参数,不变性,无副作用
因为函数不包含数据,多线程安全
#委托 delegate
delegation pattern(委托模式)
使用by关键字,把接口方法实现/属性获取委托给另一个对象,减少模板代码。
delegate methods/properties
#Object
这个关键词定义一个类并且同时创建了这个类的一个实例。
#inline funcion
编译器会把每次函数调用都替换成函数的实际代码实现。能够提升效率。
reified 修饰符,只用于inline function,告诉编译器类型将类型参数实化,类型参数在编译时不要被擦除
//Cannot check for instance of erased type: T
//fun <T> isT(obj: Any) = obj is T
inline fun <reified T> isT(obj: Any) = obj is T
#协变
保留子类型信息