B站视频: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;
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
val s1 = "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</code></pre><p><code>let</code> 、<code>also</code>、<code>run</code>、<code>apply</code> 都是通过点号 (<code>.</code>) 调用,前两个引入 <code>it</code>(或自定义变量),后两个引入 <code>this</code>;<code>also</code> 和 <code>apply</code> 返回调用者,其他的返回最后一行的计算结果。</p></li><li>属性(去 getter/setter)</li><li><p>扩展方法</p><pre><code class="kotlin">fun String.blabla() { ... }</code></pre><p>感觉比 C# 的更合理,但是不能作为静态函数调用(虽然本质就是静态函数)</p></li><li>无差别的 Lambda(想想 <code>Consumer</code>,<code>Runable</code> 等,相同签名但不同接口的 Lambda 不能互换)</li><li><p>对象解构</p><p><code>operator fun componentN()</code> 操作符方法,用于解构。<code>N</code> 从 1 开始,按顺序递增。</p></li><li><p>when 分支(Java 12 有 switch 表达式)</p><pre><code class="kotlin"> 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