is 和 !is 操作符我們可以在運(yùn)行時(shí)通過(guò)使用 is 操作符或其否定形式 !is 來(lái)檢查對(duì)象是否符合給定類(lèi)型:
if (obj is String) {
print(obj.length)
}
if (obj !is String) { // 與 !(obj is String) 相同
print("Not a String")
}
else {
print(obj.length)
}
在許多情況下,不需要在 Kotlin 中使用顯式轉(zhuǎn)換操作符,因?yàn)榫幾g器跟蹤
不可變值的 is-檢查,并在需要時(shí)自動(dòng)插入(安全的)轉(zhuǎn)換:
fun demo(x: Any) {
if (x is String) {
print(x.length) // x 自動(dòng)轉(zhuǎn)換為字符串
}
}
編譯器足夠聰明,能夠知道如果反向檢查導(dǎo)致返回那么該轉(zhuǎn)換是安全的:
if (x !is String) return
print(x.length) // x 自動(dòng)轉(zhuǎn)換為字符串
或者在 && 和 || 的右側(cè):
// `||` 右側(cè)的 x 自動(dòng)轉(zhuǎn)換為字符串
if (x !is String || x.length == 0) return
// `&&` 右側(cè)的 x 自動(dòng)轉(zhuǎn)換為字符串
if (x is String && x.length > 0) {
print(x.length) // x 自動(dòng)轉(zhuǎn)換為字符串
}
這些 智能轉(zhuǎn)換 用于 when{: .keyword }-表達(dá)式
和 while{: .keyword }-循環(huán) 也一樣:
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
請(qǐng)注意,當(dāng)編譯器不能保證變量在檢查和使用之間不可改變時(shí),智能轉(zhuǎn)換不能用。
更具體地,智能轉(zhuǎn)換能否適用根據(jù)以下規(guī)則:
通常,如果轉(zhuǎn)換是不可能的,轉(zhuǎn)換操作符會(huì)拋出一個(gè)異常。因此,我們稱(chēng)之為不安全的。
Kotlin 中的不安全轉(zhuǎn)換由中綴操作符 as{: .keyword }(參見(jiàn)operator precedence)完成:
val x: String = y as String
請(qǐng)注意,null{: .keyword } 不能轉(zhuǎn)換為 String 因該類(lèi)型不是可空的,
即如果 y 為空,上面的代碼會(huì)拋出一個(gè)異常。
為了匹配 Java 轉(zhuǎn)換語(yǔ)義,我們必須在轉(zhuǎn)換右邊有可空類(lèi)型,就像:
val x: String? = y as String?
為了避免拋出異常,可以使用安全轉(zhuǎn)換操作符 as?{: .keyword },它可以在失敗時(shí)返回 null{: .keyword }:
val x: String? = y as? String
請(qǐng)注意,盡管事實(shí)上 as?{: .keyword } 的右邊是一個(gè)非空類(lèi)型的 String,但是其轉(zhuǎn)換的結(jié)果是可空的。