我尝试使用访问者模式but等返回值。
但是,虽然没有明确的演员表,但我得到了ClassCastException:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.CharSequence;
at Printer.combine(...)
at Split.accept(...)
at MWEKt.main(...)
代码:
interface TreeElem {
fun <T> accept(visitor: TreeVisitor<T>): T
}
class Leaf: TreeElem {
override fun <T> accept(visitor: TreeVisitor<T>): T {
return visitor.visit(this)
}
}
class Split(val left: TreeElem, val right: TreeElem): TreeElem {
override fun <T> accept(visitor: TreeVisitor<T>): T {
return visitor.combine( // this causes cast error
visitor.visit(this),
left.accept(visitor),
right.accept(visitor))
}
}
interface TreeVisitor<T> {
// multiple implementations with different T in future (only one in this example)
fun visit(tree: Leaf): T
fun visit(tree: Split): T
fun combine(vararg inputs: T): T
}
class Printer: TreeVisitor<CharSequence> {
override fun combine(vararg inputs: CharSequence): CharSequence { // error here
return inputs.joinToString(" ")
}
override fun visit(tree: Leaf): CharSequence { return "leaf" }
override fun visit(tree: Split): CharSequence { return "split" }
}
fun main(args: Array<String>) {
val tree = Split(Leaf(), Leaf())
val printer = Printer()
println(tree.accept(printer))
}
我不知道问题所在。我是在尝试做一些不可能做到的事情,还是我没有正确地表达出来,或者是类型擦除使某些事情变得不可能?
到目前为止我的想法:
Printer.combine
期待CharSequence
s; TreeElem.accept
的{{1}}的泛型重载由于最后一点与现实主义者发生冲突,我可能不正确地理解错误。
编辑:我已将MWE翻译成Java,看看它是否是Kotlin问题并吸引答案:
CharSequence
Java案例的错误相同。
答案 0 :(得分:1)
我很确定这是这个问题的重复:https://stackoverflow.com/a/9058259/4465208
但是,要提供特定的解决方案,您可以将vararg
参数替换为List<T>
代替,这样就可以了:
class Split(val left: TreeElem, val right: TreeElem) : TreeElem {
override fun <T> accept(visitor: TreeVisitor<T>): T {
return visitor.combine(listOf(
visitor.visit(this),
left.accept(visitor),
right.accept(visitor)))
}
}
interface TreeVisitor<T> {
fun combine(inputs: List<T>): T
// ...
}
class Printer : TreeVisitor<CharSequence> {
override fun combine(inputs: List<CharSequence>): CharSequence {
return inputs.joinToString(" ")
}
// ...
}
不是那么漂亮,但它与泛型一致。