let函数
let函数在空指针检查中起很大作用,用对象调用,并且把自身传到lambda表达式中
obj?.let {
it.doSomething()
}
with函数
连续调用一个对象的多个方法,让代码变得精简。
val result = with(obj) {
//这里可以使用obj的相应函数
“value”//with函数的返回值
}
val list = listOf(“Apple”, “Banana”, “Orange”, “Pear”, “Grape”)
val result = with(StringBulder()) {
for (fruit in list) {
append(fruit).append(“\n")
}
toString()
}
run函数
功能和with函数差不多,不过需要依托某个对象
val list = listOf(“Apple”, “Banana”, “Orange”, “Pear”, “Grape”)
val result = StringBulder().run {
for (fruit in list) {
append(fruit).append(“\n")
}
toString()
}
apply函数
功能和with函数差不多,只是返回值是自身
val list = listOf(“Apple”, “Banana”, “Orange”, “Pear”, “Grape”)
val result = StringBulder().apply {
append(“Start eating fruits.\n”)
for (fruit in list) {
append(fruit).append(“\n")
}
append(“Ate all fruits.”)
}
repeat函数
将Lambda表达式重复执行n次
repeat(n) {
//
}
inner class定义内部类
companion object用来定义类似Java静态方法
object用来定义单例
lateinit延迟初始化
告诉编译器晚一些的时候初始化,这样就不用一开始的时候赋值为null
private lateinit var adapter: MsgAdapter
::adapter.isInitialized//用于判断变量是否初始化
密封类sealed class
when语句传入一个密封类变量作为条件的时候,Kotlin编译器会自动检查该密封类有哪些子类,并强制要求每一个子类所对应的条件全部处理
所以不用编写else条件分支
密封类和子类只能定义在同一个文件的顶层位置
可空类型系统 —— 允许为空
Int?表示可为空的整型
fun doStudy(study: Study?) {
study.readBooks()//编译会不通过
}
?.操作符
当对象不为空的时候调用对象的方法,当对象为空的时候什么都不做
fun doStudy(study: Study?) {
if(study != null) {
study.readBooks()
}
}
等价于
fun doStudy(study: Study?) {
study?.readBooks()//编译会不通过
}
?:操作符
如果左边表达式的结果不为空就返回左边表达式的结果,否则返回右边表达式的结果。
fun getTextLength(text: String?) = text?.length ?: 0
高阶函数
接收函数类型的参数,或者返回的类型是一个函数类型的函数,则称这个函数为高阶函数。
下面这个函数就是一个高阶函数
fun num1AndNum2(num1:Int, num2:Int, operation:(Int,Int) -> Int): Int {
}
内联函数inline
避免Lambda表达式在运行时创建匿名对象
inline fun num1AndNum2(num1:Int, num2:Int, operation:(Int, Int) -> Int): Int {
val result = operation(num1, num2)
return result
}
首先把lambda表达式的内容替换到函数类型调用的地方,接着把整个内联函数替换到调用内联函数的地方。
use函数
运行结束的时候会自动关闭流
try {
writer.use {
//
}
} catch(e: Exception) {
//
}
by lazy Kotlin中提供的一种懒加载技术
泛型 定义泛型类或定义泛型方法
- <T> //定义一个泛型类 类中的方法允许使用T类型的参数和返回值
class MyClass<T> {
fun method(param: T) : T {
}
}
val myClass<Int>()
val result = myClass.method(123)
- 定义一个泛型方法
class MyClass {
fun <T> method(param: T) : T {
}
}
val myClass = MyClass()
val result = myClass.method(123)
泛型的上界默认是Any?可空类型,如果不想为空需要手动改成Any
泛型实化
inline fun <reified T> getGenericType() = T::class.java
- 泛型实化和高阶函数的应用
inline fun <reified T> startActivity(context: Context, block: Intent.() -> Unit){
val intent = Intent(context, T::class.java)
intent.block()
context.startActivity(intent)
}
委托
操作对象不会自己去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理。使用by关键字
- 类委托:把一个类的具体实现委托给另一个类去完成
//定义了一个MySet类拥有和HashSet一样的方法,具体的实现是委托给HashSet去完成
class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helper {
}
- 委托属性:把一个属性的具体实现委托给另一个类去完成(by lazy的实现原理)
class MyClass {
var p by Delegate()
}
class Delegate {
var propValue: Any? = null
//第一个参数表明这个委托类可以在哪个类中使用 第二个先忽略
operator fun getValue(myClass: MyClass, prop: KProperty<*>): Any? {
return propValues
}
//第三个参数表示具体要赋值给委托属性的值
operator fun setValue(myClass: MyClass, prop: KProperty<*>, value: Any?) {
propValue = value
}
}
Lazy可以理解为是一个顶层函数,接受一个函数类型的参数,用这个函数类型的参数去传给Delegate代理类的构造函数,最终返回一个T类型。