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

Dod*_*ion 7 kotlin

有什么区别

x as? String
Run Code Online (Sandbox Code Playgroud)

x as String?
Run Code Online (Sandbox Code Playgroud)

它们似乎都产生了一种String?类型.在科特林页面不回答对我来说.

更新:

澄清一下,我的问题是:

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

Kis*_*kae 20

不同之处在于何时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.
Run Code Online (Sandbox Code Playgroud)


Zoe*_*Zoe 6

as?安全的类型转换运算符。这意味着如果转换失败,它将返回 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
}
Run Code Online (Sandbox Code Playgroud)

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

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