为什么 Kotlin 不能隐式地将字符串数组转换为任意数组?
Why can't Kotlin implicitly upcast Array of String into Array of Any?
以下代码隐式地将 String 向上转换为 Any。
val s = "some string"
val upcasted: Any = s
但是,以下内容无法编译(类型不匹配):
val s = arrayOf("some string")
val upcasted: Array<Any> = s
您可以成功转换为 Array<Any>
,如图所示:
val s = arrayOf("some string")
val upcasted: Array<Any> = s as Array<Any>
然而,这给出了警告"Unchecked cast: Array<String> to Array<Any>"
。
同样的逻辑似乎也适用于列表,那么数组的内部实现是否与这种类型的转换不兼容?也许是因为数组在内存中的表示?
您不能像这样安全地将类型转换为超类型或子类型,因为 Array<String>
不符合 Array<Any>
的条件。如果您尝试将 Double 放入假定的 Array<Any>
中,它会引发异常,因为实际类型是 String 数组。数组是泛型的一种特殊情况,没有类型擦除,因此它们被锁定为实例化时使用的类型。
您可以将其转换为 Array<out Any>
,因为您可以安全地使用它。您可以从数组中提取字符串 out,它们符合 Any 的实例。反之则不然。您不能将 Any 及其子类的任何实例放入 String 数组中。
对于List,你可以将它转换为超类型的List,甚至不需要手动转换。它是安全的,因此可以隐式完成转换。
val s = listOf("some string")
val upcasted: List<Any> = s // implicit cast
那你为什么不用强制转换为 List<out Any>
? List 接口没有任何允许您向其添加内容的功能。它在其声明中使用 out
投影类型定义,因此当您键入 List<Any>
时,它已经与 List<out Any>
相同
如果您尝试使用 MutableList 执行此操作,它接受将项目放入其中并且未使用 out
投影类型定义,那么您将 运行 进入与您相同的警告对数组做了。
val s = mutableListOf("some string")
val upcasted: MutableList<Any> = s as MutableList<Any> // warning here and implicit cast impossible
它与 Array 的区别在于存在类型擦除,因此如果您尝试向该列表添加一些非字符串,则不会出现 运行time 异常。但是一不小心就有可能隐藏bug,所以警告。
以下代码隐式地将 String 向上转换为 Any。
val s = "some string"
val upcasted: Any = s
但是,以下内容无法编译(类型不匹配):
val s = arrayOf("some string")
val upcasted: Array<Any> = s
您可以成功转换为 Array<Any>
,如图所示:
val s = arrayOf("some string")
val upcasted: Array<Any> = s as Array<Any>
然而,这给出了警告"Unchecked cast: Array<String> to Array<Any>"
。
同样的逻辑似乎也适用于列表,那么数组的内部实现是否与这种类型的转换不兼容?也许是因为数组在内存中的表示?
您不能像这样安全地将类型转换为超类型或子类型,因为 Array<String>
不符合 Array<Any>
的条件。如果您尝试将 Double 放入假定的 Array<Any>
中,它会引发异常,因为实际类型是 String 数组。数组是泛型的一种特殊情况,没有类型擦除,因此它们被锁定为实例化时使用的类型。
您可以将其转换为 Array<out Any>
,因为您可以安全地使用它。您可以从数组中提取字符串 out,它们符合 Any 的实例。反之则不然。您不能将 Any 及其子类的任何实例放入 String 数组中。
对于List,你可以将它转换为超类型的List,甚至不需要手动转换。它是安全的,因此可以隐式完成转换。
val s = listOf("some string")
val upcasted: List<Any> = s // implicit cast
那你为什么不用强制转换为 List<out Any>
? List 接口没有任何允许您向其添加内容的功能。它在其声明中使用 out
投影类型定义,因此当您键入 List<Any>
时,它已经与 List<out Any>
如果您尝试使用 MutableList 执行此操作,它接受将项目放入其中并且未使用 out
投影类型定义,那么您将 运行 进入与您相同的警告对数组做了。
val s = mutableListOf("some string")
val upcasted: MutableList<Any> = s as MutableList<Any> // warning here and implicit cast impossible
它与 Array 的区别在于存在类型擦除,因此如果您尝试向该列表添加一些非字符串,则不会出现 运行time 异常。但是一不小心就有可能隐藏bug,所以警告。