kotlin - 为什么我的通用 Kotlin 函数中的此转换未被选中?

标签 kotlin generics casting

看看这个 MVCE:

abstract class Bar

class BarHolder(val barFunctor : Bar.()-> Unit)

fun <T : Bar>foo(bar: T.() -> Unit) {
    val activeRequest = BarHolder(bar as (Bar.() -> Unit))
}

Actor 阵容bar as (Bar.() -> Unit)被标记为未选中。但我无法想到在运行时强制转换失败的场景,因为 T始终是 Bar 的子类,不是吗?

我知道我可以通过添加 @Suppress("UNCHECKED_CAST") 来忽略它但这对我来说似乎是不好的做法。那么避免不安全强制转换的正确方法是什么?

有关更多上下文,预期用例类似于:

class LongBar : Bar()
    val length = 69

fun foobar(){
    foo<LongBar>(){
        println(length)
    }
}

最佳答案

您的代码不是类型安全的,并且 Kotlin 是正确的,因此不应被允许。

问题是您可能有一个非常特定类型的 Bar 的使用者,例如 Bar1,然后您将其转换为任何 Bar 的使用者 对象。如果您随后使用 Bar1 的使用者并向其传递一个 Bar2 对象会怎么样?

fun main() {
    val bar1Consumer: Bar1.() -> Unit = { toString() }
    val holder = foo(bar1Consumer)
    holder.barFunctor.invoke(Bar2()) // ClassCastException
}

fun <T : Bar>foo(bar: T.() -> Unit) = BarHolder(bar as (Bar.() -> Unit))

class Bar1 : Bar()
class Bar2 : Bar()

很难与您的真实示例联系起来,因为我们不知道 foo() 中到底发生了什么,但请注意,在未经检查的强制转换之后,这是允许的,并且会抛出 ClassCastException:

val activeRequest = BarHolder(bar as (Bar.() -> Unit))
activeRequest.barFunctor.invoke(IntBar())

关于kotlin - 为什么我的通用 Kotlin 函数中的此转换未被选中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76502342/

相关文章:

swift - 无法在 Swift 中使用 KeyType 类型的参数列表调用方法

python - 覆盖自定义类的 bool()

android - 使用 ML 套件从位图中读取条形码信息

android - 将 android camera2 图像保存为无损 PNG

android - 选择字符串中的前 X 位数字并将每个数字替换为 Character

ios - 将泛型应用于变量和函数 - Swift

Java 泛型仅支持预定义的数据类型

从空字节数组转换为结构指针会违反严格别名吗?

java - 类层次结构和对象之间的转换

java - 删除布局中按/触摸时的深色高光