kotlin
函数
普通函数
- 函数体只有一行代码可以写在函数尾部
标准函数
-
let
- 搭配 ?. 使用 减少对象方法的空判断
-
with
- 将with的第一个参数作为这个方法体的上下文 直接调用对象的方法 比如传入StringBuilder 直接在方法体中 append 不用调用 StringBuilder.append 最后一行为返回值
-
run
- 与witch类似不过是调用对象的run方法 不能直接调用
-
apply
- 与run类似 不过不能确定返回值 只能返回对象本身 可在intent 跳转时 .apply {putExtra()}
-
repeat
- 重复执行一段代码的 repeat(3){} 3是次数
静态函数
-
companion object
- 可以作为静态调用而不是静态方法
-
@JvmStatic
- 方法加注解为真正的静态方法,只能加在单例类和companion object中的方法上
-
创建kotlin file 声明1个顶层方法就可以在任意位置调用
扩展函数
- KTX 库提供了 contentValuesOf() 保存SP值
面向对象编程
类与构造函数
-
主构造函数
- 不带参数,没有函数体
- 主构造函数逻辑写在init结构体中
-
次构造函数
- 有函数体,必须调用主构造
可继承类
- 用 open 修饰
数据类
- data修饰
单例类
- object修饰
密封类
- sealed class 修饰类 ,在when语句中传入密封类变量作为条件,kotlin会检查子类,强制子类处理对应条件,省去编写else情况
接口
- 用冒号:取代extends 和 implements 用,号隔开多个
- 接口中函数有了函数体就是默认实现的
延迟初始化
- 可以不用在一开始将变量赋值为空 用 lateinit 修饰
- !::adapter.isInitialized 判断是否初始化
空指针检查
可空类型系统
- kotlin 默认所有参数和变量都不可为空,用?修饰数据类型 代表可空数据类型,需在使用处做空判断处理
判空辅助工具
- ?. 当对象不为空时正常调用响应的方法 为空时则什么都不做
- ?: 相当于三元运算符 比如 a ? : b 代表如果a为空返回b
- !! 相当于告诉kotlin 前边的值一定不为空
委托
类委托
- by 关键字 将一个类的具体实现委托给另一个类完成
委托属性
- 讲一个属性的具体实现委托给另一个类完成 另一个类实现 getValue 和 setValue 方法 并用operator 声明 get第一个参数类名 第二个是kotlin 属性操作符 set 前两个参数一样 第三个参数 赋给委托属性的值
lazy函数
- 延迟执行代码块 只会执行一次
协程
作用域创建
- GlobalScope.launch{} 顶层协程 运行时间受应用影响
- runBlocking{ launch{} launch{} } 子协程 可运行完毕 子协程是并行的
- coroutineScope{ repeat(1000){ launch{} } } 创建一万个协程 runBlocking 作用域 会阻塞当前线程 不推荐使用 通常使用 coroutineScope 只阻塞当前协程
- suspend 修饰方法 变为挂起函数 挂起函数之间可相互调用 coroutineScope 也可创建作用域
- 取消协程 是通过作用域返回对象 调用 cancel()
高性能并发编程
- runBlocking{ val result=async{ 5+5 }.await println(result) } 能够返回作用域的结果 但是多个子协程 是串行的 去掉.await 这个方法 变为并行
- runBlocking{ val result=withContext(Dispatchers.Default){} } 其中 Dispatchers.Default 代表会使用一种默认低并发的线程策略 Dispatchers.IO 表示高并发 Dispatchers.Main 表示不会开启子线程
简化回调的写法
- suspendCoroutine 简化回调 必须在携程作用于或者挂起参数中使用 接收一个Lambda表达式作为参数 会传入一个Continuation 参数 调用他的resume 或 resumeWithException 让协程恢复执行
- suspend fun getBaiduResponse(){ try{ val response=request("baidu") //对响应数据处理 }catch(e:Exception){ //服务器返回异常 } } request 方法内部封装了请求和回调 调用了continuation.resume(response)
变量
val
- 不可变的变量
var
- 可变的变量
lateinit
- 延迟初始化 lateinit 只用于变量 var,而 lazy 只用于常量 val
逻辑控制
判断
-
if
-
when
- 相当于switch并支持多种类型数据,可在判断时通过==以外方法匹配
循环
-
while
-
for-in
- val range = 0 until 10 和 val range = 0 until 10的区别是 0-10和0-9
循环中可用step 跳过元素 降序在for循环中加入 downTo
- val range = 0 until 10 和 val range = 0 until 10的区别是 0-10和0-9
区间
- until
- downTo
Lambda编程
集合的函数式API
- Lambda 一小段可以称作为参数传递的代码
- 结构体 {参数名1:参数类型,参数名2:参数类型 -> 函数体}
- 不可变集合val list=listOf("1","2")
- 可变集合 val list = mutableListOf("1","2")
- setOf 对应set集合
- mapOf对应Map集合通过 map[key]=value 添加
- filter 过滤 list.filter{}
- any 函数判断集合中是否存在一个满足指定条件 all 函数判断集合中所有元素是否都满足指定条件
java函数式API
- kotlin 创建匿名类实例 用 object 而java中用new
高阶函数
-
基本概念
- 一个函数接收另一个函数作为参数或者返回值类型是函数 函数中的函数参数 用 (::函数名) 表示 也可用Lambda 表达式将作为参数的函数体写在外部函数中
-
内联函数
-
inline
- 关键字放在函数最前方 将Lambda运行时开销完全消除 允许使用return关键字
-
noinline
- 多个函数作为参数 单个不内联时使用 内联的函数类型参数只允许传递给另外一个内联函数
-
crossinline
- 因高阶函数匿名类实现中不允许使用return关键字,用这个修饰内联函数 是保证函数中不使用return 但可使用retrun@方法名 进行局部返回
-
-
DSL
- Gradle 是基于Groovy 的语言构建工具 导库 就是DSL功能 可轻松生成任意表格对应的html代码
-
实际应用
- 封装好用的工具类 max(a,b,c) String.showToast(context) View.showSnackbar("xxx","action")
泛型
普通泛型
- T 表示 与java一样 上界指定Any 表示不能为空
泛型实化
- 函数必须是内联函数 声明泛型的地方加上reified 修饰泛型 新建一个reified.kt文件 inline fun startActivity(context:Context,block:Intent.() -> Unit){ val intent=Intent(context,T::class.java) intent.block() context.startActivity(intent) } 调用时 直接 srartActivity(context){ putExtra("param1","data") }
协变和逆变
- 协变 A是B的子类 MyClass 又是 MyClass 的子类 可称MyClass 泛型协变 用out 修饰泛型 泛型只能出现在out位置上不能出现在in位置 参数就可从A 转换成B List 从源码查看就是协变的
- 逆变 A是B的子类 MyClass 是 MyClass 的子类 可称MyClass 泛型逆变 用in 修饰泛型 传参不受限制
其他
字符串内嵌表达式
- 拼接字符串时使用 {key} 可打印值
函数参数默认值
- 写在声明参数时用=号设置,不传这个参数时用默认参数 调用方法时传参也可用
运算符重载
- 函数用operator 修饰 重载运算符的方法处理数据 直接调用语法糖表达式即可
infix函数
- 把编程语言函数调用规则调整了 A to B 实际等于 A.to (B) 函数最前加 infix 不能定位顶层函数 作为类的成员函数 只能接受一个参数 一般用于简单的比较等
扩展函数
- 用ClassName. 修饰函数名称class是对象名 比如 String.
XMind - Trial Version