鍍金池/ 教程/ Android/ Kotlin類型的檢查與轉換
Kotlin內聯(lián)函數(shù)
Kotlin開發(fā)環(huán)境設置(Eclipse)
Kotlin調用Java代碼
Kotlin使用Ant
Kotlin編譯器插件
Kotlin相等性
Kotlin JavaScript模塊
編寫Kotlin代碼文檔
Kotlin返回和跳轉
Kotlin異常處理
Kotlin可見性修飾符
Kotlin委托
Kotlin委托屬性
Kotlin編碼約定/編碼風格
Kotlin基礎語法
使用Kotlin進行服務器端開發(fā)
Kotlin接口
Kotlin反射
Kotlin類型別名
Kotlin枚舉類
Kotlin當前版本是多少?
Kotlin注解處理工具
Kotlin類型的檢查與轉換
Kotlin屬性和字段
Kotlin類型安全的構建器
Kotlin相比Java語言有哪些優(yōu)點?
Kotlin JavaScript反射
Kotlin 是什么?
Kotlin泛型
Kotlin慣用語法
Kotlin與OSGi
Kotlin數(shù)據(jù)類型
Kotlin是面向對象還是函數(shù)式語言?
Kotlin動態(tài)類型
Kotlin協(xié)程
Kotlin操作符符重載
Kotlin使用Gradle
Kotlin密封類
Kotlin兼容性
Kotlin集合
Kotlin調用JavaScript
Kotlin null值安全
Kotlin函數(shù)
Kotlin開發(fā)環(huán)境設置(IntelliJ IDEA)
Kotlin嵌套類
Kotlin控制流程
Kotlin和Java語言比較
Kotlin 與 Java 語言兼容嗎?
Kotlin教程
Kotlin類和繼承
Kotlin對象表達式和對象聲明
JavaScript中調用Kotlin
Kotlin區(qū)間/范圍
Kotlin數(shù)據(jù)類
Kotlin lambda表達式
Kotlin是免費的嗎?
Kotlin包
使用Kotlin進行Android開發(fā)
在Java中調用Kotlin代碼
Kotlin this表達式
使用Kotlin進行JavaScript開發(fā)
Kotlin擴展
Kotlin解構聲明
Kotlin注解
Kotlin使用Maven

Kotlin類型的檢查與轉換

is!is 操作符

我們可以在運行時通過使用 is 操作符或其否定形式 !is 來檢查對象是否符合給定類型:

if (obj is String) {
    print(obj.length)
}

if (obj !is String) { // 與 !(obj is String) 相同
    print("Not a String")
}
else {
    print(obj.length)
}

智能轉換

在許多情況下,不需要在 Kotlin 中使用顯式轉換操作符,因為編譯器跟蹤
不可變值的 is-檢查,并在需要時自動插入(安全的)轉換:

fun demo(x: Any) {
    if (x is String) {
        print(x.length) // x 自動轉換為字符串
    }
}

編譯器足夠聰明,能夠知道如果反向檢查導致返回那么該轉換是安全的:

    if (x !is String) return
    print(x.length) // x 自動轉換為字符串

或者在 &&|| 的右側:

    // `||` 右側的 x 自動轉換為字符串
    if (x !is String || x.length == 0) return

    // `&&` 右側的 x 自動轉換為字符串
    if (x is String && x.length > 0) {
        print(x.length) // x 自動轉換為字符串
    }

這些 智能轉換 用于 when{: .keyword }-表達式
while{: .keyword }-循環(huán) 也一樣:

when (x) {
    is Int -> print(x + 1)
    is String -> print(x.length + 1)
    is IntArray -> print(x.sum())
}

請注意,當編譯器不能保證變量在檢查和使用之間不可改變時,智能轉換不能用。
更具體地,智能轉換能否適用根據(jù)以下規(guī)則:

  • val{: .keyword } 局部變量——總是可以;
  • val{: .keyword } 屬性——如果屬性是 private 或 internal,或者該檢查在聲明屬性的同一模塊中執(zhí)行。智能轉換不適用于 open 的屬性或者具有自定義 getter 的屬性;
  • var{: .keyword } 局部變量——如果變量在檢查和使用之間沒有修改、并且沒有在會修改它的 lambda 中捕獲;
  • var{: .keyword } 屬性——決不可能(因為該變量可以隨時被其他代碼修改)。

“不安全的”轉換操作符

通常,如果轉換是不可能的,轉換操作符會拋出一個異常。因此,我們稱之為不安全的。
Kotlin 中的不安全轉換由中綴操作符 as{: .keyword }(參見operator precedence)完成:

val x: String = y as String

請注意,null{: .keyword } 不能轉換為 String 因該類型不是可空的,
即如果 y 為空,上面的代碼會拋出一個異常。
為了匹配 Java 轉換語義,我們必須在轉換右邊有可空類型,就像:

val x: String? = y as String?

“安全的”(可空)轉換操作符

為了避免拋出異常,可以使用安全轉換操作符 as?{: .keyword },它可以在失敗時返回 null{: .keyword }:

val x: String? = y as? String

請注意,盡管事實上 as?{: .keyword } 的右邊是一個非空類型的 String,但是其轉換的結果是可空的。