我正在通过从Map<String, Any>Kotlin 中的a 加载数据来初始化一个类。由于此 Map 是直接从 JSON 收集的,因此我不确定是否存在任何给定的键,或者它的值是否属于我期望的类型。为了安全地打开这张地图,我正在执行以下操作,这似乎工作得很好:
a = rawData["A"] as? String ?: ""
Run Code Online (Sandbox Code Playgroud)
其中一些数据位于进一步嵌套的 JSON 中,我将其解压缩为数组;我试图以同样的方式做到这一点:
b = rawData["B"] as? Array<String> ?: arrayOf<String>()
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用数组(如上所述)进行此操作时,IntelliJ 大惊小怪,说
警告:(111, 30) Kotlin:未经检查的演员表:有吗?到数组<字符串>
这只是 IDE 使自己陷入困境,还是这种方法对于 Arrays 真的不安全,尽管对于其他类型似乎完全安全?
Cai*_*son 10
对于此问题的任何未来读者,请使用解决方案扩展已接受的答案:
要在 Kotlin 中安全地将 Any 转换为特定类型的数组,您必须首先转换为无类型数组(请参阅上面 zsmb13 的答案以了解原因),然后将该数组过滤为所需的类型。
例如,要input: Any转换为String实例数组,您可以调用:
val inputAsArray = (input as? Array<*>)?.filterIsInstance<String>()
Run Code Online (Sandbox Code Playgroud)
我准备将其称为错误,因为它Array是一个具体化的类型,这意味着它的泛型参数实际上可以在运行时检查(List例如,与 a 不同)。我已经尝试查看它是否已经提交,结果证明编译器向您显示警告实际上是正确的。正如您在对这个问题的回应中看到的那样,这种类型的强制转换仍然存在可空性问题。
val a = arrayOf("foo", "bar", null) as Array<String>
println(a[2].length)
Run Code Online (Sandbox Code Playgroud)
像这个例子中的数组被成功转换(使用as,它们不抛出异常,使用as?,它们不返回null),但是,转换不能确保这是一个Array<String>,只能确保它是一个Array<String?>。
这意味着您可以稍后null从类型为Array<String>after强制转换的变量中读取值,编译器不会发出进一步警告。
| 归档时间: |
|
| 查看次数: |
8042 次 |
| 最近记录: |