B站视频:https://www.bilibili.com/vide...
语法层面
可空对象(和 C# 的
<Nullable>enabled</Nullable>
相似)Int
和Int?
是两种不同的类型;String
和String?
也是两种不同的类型(前者是后者的子类型)var a: Int = 0; var b: Int? = 0; a = b; // ⇐ 不能将 Int? 赋值给 Int b = a;
不可变类型/可变类型
val
声明不可变变量,不可再赋值;var
声明可变变量,能再赋值。var a = 0; val b = 1; a = b; b = a; // ⇐ 不能对 val 变量赋值
字符串插值
val PI = 3.1415926 val s1 = "PI is ${PI}"; // PI is 3.1415926 val s2 = "PI is ${String.format("%.2f", PI)}"; // PI is 3.14
字符串插值语法不支持设置格式(这点不如 C# 方便)
对函数式编程的支持,一切都是表达式
没有条件(三目)运算符,因为
if
分支就能做到(只是写起来字多一点)fun fixInt(value: Int?): Int { val n = value ?: 0; return if (n >= 0) n else -n; // C# 的 int? 可以参与运算,这点不同 }
when
甚至try ... catch
都可以作为表达式fun devide(m: Int, n: Int) { return try { m / n } catch (e: ArithmeticException) { 0 } }
函数式编程支持:
with
、also
、let
、run
、apply
上面的
fixInt
可以用let
来改写,注意是?.let
表示let
块里的it
是不含空的类型fun fixInt(value: Int?): Int { return value?.let { if (it >= 0) it else -it } ?: 0 }
with(obj)
块中会把this
引用到obj
对象上去,而this.
在不冲突的情况下是可以省略的with ("Hello World") { println("`${this}` has ${length} characters") } // `Hello World` has 11 characters
let
、also
、run
、apply
都是通过点号 (.
) 调用,前两个引入it
(或自定义变量),后两个引入this
;also
和apply
返回调用者,其他的返回最后一行的计算结果。- 属性(去 getter/setter)
扩展方法
fun String.blabla() { ... }
感觉比 C# 的更合理,但是不能作为静态函数调用(虽然本质就是静态函数)
- 无差别的 Lambda(想想
Consumer
,Runable
等,相同签名但不同接口的 Lambda 不能互换) 对象解构
operator fun componentN()
操作符方法,用于解构。N
从 1 开始,按顺序递增。when 分支(Java 12 有 switch 表达式)
when (view) { is TextView -> toast(view.text) is RecyclerView -> toast("Item count = ${view.adapter.itemCount}") is SearchView -> toast("Current query: ${view.query}") else -> toast("View type not supported") }
工具(案例演示)
- 返转一个数组
int[]
- 字符串工具函数,比如
padStart
,orEmpty
等 - 类似 stream,但更简洁,
forEachIndexed
- 快速创建 List 和 Map
- 把一大断
byte[]
转成十六进制并按每行 16 个字节的格式输出(文本)
其他
- 协程和
await
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。