安全施法vs强制转换为可空

时间:2018-06-13 11:24:34

标签: kotlin

之间有什么区别
x as? String

x as String?

他们似乎都生成String?类型。 Kotlin page并没有为我回答。

更新:

澄清一下,我的问题是:

拥有as?运算符的目的是什么,因为对于任何对象x和任何类型T,表达式x as? T都可以(我认为) )改写为x as T?

2 个答案:

答案 0 :(得分:16)

区别在于x是不同的类型:

val x: Int = 1

x as String? // Causes ClassCastException, cannot assign Int to String?

x as? String // Returns null, since x is not a String type.

答案 1 :(得分:2)

as?safe type cast运算符。这意味着如果转换失败,则返回null而不是抛出异常。文档还声明返回的类型是可以为null的类型,即使将其转换为非null类型也是如此。这意味着:

fun <T> safeCast(t: T){
    val res = t as? String //Type: String?
}

fun <T> unsafeCast(t: T){
    val res = t as String? //Type: String?
}

fun test(){
    safeCast(1234);//No exception, `res` is null
    unsafeCast(null);//No exception, `res` is null
    unsafeCast(1234);//throws a ClassCastException
}

安全铸造操作员的重点是安全铸造。在上面的例子中,我使用原始的String示例作为类型。当然,Int上的unsafeCast会抛出异常,因为Int不是String。 safeCast没有,但res最终为空。

主要区别在于类型,但它如何处理铸造本身。 variable as SomeClass?会在不兼容的类型上抛出异常,而variable as? SomeClass则不会,并返回null。