通过编译以下示例代码会出错。
abstract class Base
case class A(i: Int) extends Base
case class B(s: String) extends Base
class Transform {
def func[T <: Base](arg: T): T = arg match {
case A(i) => A(i)
case B(s) => B(s)
}
}
错误是
Example.scala:9: error: type mismatch;
found : A
required: T
case A(i) => A(i)
^
Example.scala:10: error: type mismatch;
found : B
required: T
case B(s) => B(s)
^
two errors found
这些错误是合理的。
为避免这种情况,我需要将asInstanceOf[T]
放在类似A(i).asInstanceOf[T]
的实例化后面。但是,如果有很多区分大小写的模式,那么对于所有返回值都这样做是很烦人的。
此外,我想使用Transform
类作为父类并重写func()
以执行特定的操作,如下面的代码。
class ExtTransform extends Transform {
override def func[T <: Base](arg: T): T = arg match {
case A(i) => A(i + 1)
case _ => super.func(arg)
}
}
有更好的方法或技巧吗?
答案 0 :(得分:3)
为避免这种情况,我需要将asInstanceOf [T]放在实例化之后,例如A(i).asInstanceOf [T]。但是,如果有很多区分大小写的模式,那么对于所有返回值都这样做是很烦人的。
这个问题很容易解决:在比赛结束时将它放在一个位置,而不是每个分支。
override def func[T <: Base](arg: T): T = (arg match {
case A(i) => A(i)
case B(s) => B(s)
}).asInstanceOf[T]
但是请注意,您的设计本质上是不安全的,因为除了Base
,Base
和A
之外还有B
的子类型:单例类型(a.type
),复合类型(A with SomeTrait
,Null
...,其中任何一种都可以用作T
。最好有过载:
class Transform {
def func(arg: Base): Base = arg match {
case arg: A => func(arg)
case arg: B => func(arg)
}
def func(arg: A): A = arg
def func(arg: B): B = arg
}
class ExtTransform extends Transform {
override def func(arg: A): A = A(arg.i + 1)
}
答案 1 :(得分:0)
我建议改用 typeclass 。
- GODEBUG=netdns=go