看看这个 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/