Kotlin 型別的檢查與轉換“is”與“as”
阿新 • • 發佈:2019-02-19
1,是與!是操作符
可以我們在執行時通過使用 is
操作符或其對劃線部分形式 !is
來檢查物件是否符合給定型別:
if (obj is String) {
print(obj.length)
}
if (obj !is String) { // 與 !(obj is String) 相同
print("Not a String")
}
else {
print(obj.length)
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
2,智慧轉換
在許多情況下,不需要在Kotlin中使用顯式轉換操作符,因為編譯器跟蹤不可變變的is-檢查以及顯式轉換,並在需要時自動插入(安全的)轉換:
fun demo(x: Any) {
if (x is String) {
print(x.length) // x 自動轉換為字串
}
}
- 1
- 2
- 3
- 4
- 五
編譯器足夠聰明,能夠知道如果反向檢查導致返回那麼該轉換是安全的:
if (x !is String) return
print(x.length) // x 自動轉換為字串
- 1
- 2
或者在&&和|| 的右側:
// `||` 右側的 x 自動轉換為字串
if (x !is String || x.length == 0) return
// `&&` 右側的 x 自動轉換為字串
if (x is String && x.length > 0) {
print(x.length) // x 自動轉換為字串
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
這些智慧轉換用於when-表示式和while-迴圈也一樣:
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
- 1
- 2
- 3
- 4
- 五
請注意,當編譯器不能保證變數在檢查和使用之間不可改變時,智慧轉換不能用。更具體地,智慧轉換能否適用根據以下規則:
- val區域性變數 - 總是可以;
- val屬性 - 如果屬性是private或internal,或者該檢查在宣告屬性的同一模組中執行。智慧轉換不適用於open的屬性或者具有自定義getter的屬性;
- var區域性變數 - 如果變數在檢查和使用之間沒有修改,並且沒有在會修改它的lambda中捕獲;
- var屬性 - 決不可能(因為該變數可以隨時被其他程式碼修改)。
3,“不安全的”轉換操作符
通常,如果轉換是不可能的,轉換操作符會丟擲一個異常。因此,我們稱之為不安全的.Kotlin中的不安全轉換由中綴操作符as(參見operator precedence)完成:
val x: String = y as String
- 1
請注意,null不能轉換為String因該型別不是可空的,即如果y為空,上面的程式碼會丟擲一個異常。為了匹配Java轉換語義,我們必須在轉換右邊有可空型別,就像:
val x: String? = y as String?
- 1
4,“安全的”(可空)轉換操作符
為了避免丟擲異常,可以使用安全轉換操作符作為?,它可以在失敗時返回null:
val x: String? = y as? String
- 1
請注意,儘管事實上?的右邊是一個非空型別的String,但是其轉換的結果是可空的。