为什么我的泛型Kotlin函数中的这个强制转换未被选中?

lymnna71  于 2023-06-24  发布在  Kotlin
关注(0)|答案(1)|浏览(141)

看看这个MVCE:

abstract class Bar

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

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

强制转换bar as (Bar.() -> Unit)标记为未选中。但是我想不出在运行时强制转换失败的情况,因为T总是Bar的子类,不是吗?
我知道我可以通过添加@Suppress("UNCHECKED_CAST")来忽略它,但这对我来说似乎是不好的做法。那么,怎样才能避免不安全的演员阵容呢?
关于更多的上下文,预期的用例看起来类似于:

class LongBar : Bar()
    val length = 69

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

hjzp0vay1#

您的代码不是类型安全的,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())

相关问题