鉴于下面的示例,如何在不进行强制转换的情况下使代码编译
myMethod
?
object Test {
sealed trait MyTrait
case class A(v: Int) extends MyTrait
case class B(v: Int) extends MyTrait
def myMethod[T <: MyTrait](in0: T): T = {
in0 match {
case in: A => in.copy(v = 1)
case in: B => in.copy(v = 2)
}
}
}
谢谢。
您可以尝试:
identity
in
值相同的值例如你可以这样实现
import scala.annotation.nowarn
sealed trait MyTrait
case class A(v: Int) extends MyTrait
case class B(v: Int) extends MyTrait
@nowarn
def myMethod[T <: MyTrait](in0: T): T = {
case class IntoT[A, B](value: A, upcast: A => B)
IntoT(in0, identity[T]) match {
case IntoT(in : A, upcastA: (A => T)) => upcastA(in.copy(v = 1))
case IntoT(in : B, upcastB: (B => T)) => upcastB(in.copy(v = 2))
}
}
这将使类型不匹配的错误消失。相反,您会收到警告
match may not be exhaustive.
It would fail on pattern case: IntoT(_, _)
反过来可以用
@nowarn
来抑制。
但是,说实话,在这种情况下,当我知道我比编译器更了解时 - 因为代码很琐碎且一目了然,而且我还用测试来覆盖它 -
.asInstanceOf
并没有那么糟糕。有时您无法避免它,因此最好创建一些小型的、经过良好测试的实用程序,这将有助于处理编译器不太智能的所有情况。
object Test {
sealed trait MyTrait[T]{
def copy(v: Int): T
}
case class A(v: Int) extends MyTrait[A]
case class B(v: Int) extends MyTrait[B]
def myMethod[T <: MyTrait[T]](in0: T): T = {
in0 match {
case _: A => in0.copy(v = 1)
case _: B => in0.copy(v = 2)
}
}
}