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