看看这段代码。
trait SomeMix {
}
trait Processor[T] {
def processMix(t: T with SomeMix) = {
println("processing T with Mix")
}
def processAsUsual(t:T)= {
println("processing T")
}
def process(t:T) = {
t match {
case mix: SomeMix => processMix(mix) // <---- error here
case _ => processAsUsual(t)
}
}
}
愚蠢的Scala编译器在此处显示错误:
错误:(22,39)类型不匹配; 找到:mix.type(具有基础类型SomeMix) 必需:T与SomeMix 案例混合:SomeMix => processMix(mix)
我不知道我匹配SomeMix的表达式已经是T类型。Ok可以帮助他。更改的代码:
def process(t:T) = {
t match {
case mix: T with SomeMix => processMix(mix) // <---- warning here
case _ => processAsUsual(t)
}
}
现在,它同意一切正确,但显示警告:
警告:(22,17)抽象类型模式T未选中,因为通过擦除将其消除了 案例混合:使用SomeMix => processMix(mix)
有什么好的方法可以避免错误和警告吗?
答案 0 :(得分:2)
Scala编译器并不愚蠢。由于类型擦除,您无法检查t是T with SomeMix
的实例。代替动态类型分派,请尝试将类型类与静态分派一起使用。
例如
trait SomeMix {
def someMethod: String = "test2"
}
class SomeType
def process[T](t: T)(implicit P: Process[T]): Unit = P.process(t)
trait Process[T] {
def process(t: T): Unit
}
implicit val processString: Process[SomeType] = s =>
println(s"processing $s as usual")
implicit val processStringWithSomeMix: Process[SomeType with SomeMix] = s =>
println(s"processing $s with mix ${s.someMethod}")
process(new SomeType)
process(new SomeType with SomeMix)
答案 1 :(得分:1)
喜欢吗?
var counter=0;
while (true) {
for (i = 0; i < 5; i++) {
debugger; //enter this through Chrome Dev then press CTRL s to save
counter++;
}
}
答案 2 :(得分:1)
您可以像@ppressives建议的那样在编译时执行此操作。 如果您真的想在运行时执行此操作,则应该找到一种在编译后将类型保留在那里的方法。用Scala的标准方法是TypeTags。
尝试
import reflect.runtime.universe.{TypeTag, typeOf}
def typ[A: TypeTag](a: A) = typeOf[A]
def process(t: T)(implicit ev: TypeTag[T with SomeMix], ev1: TypeTag[T]) = {
t match {
case mix if typ(t) <:< typeOf[T with SomeMix] => processMix(mix.asInstanceOf[T with SomeMix])
case _ => processAsUsual(t)
}
}
val p = new Processor[Int] {}
p.process(10) //processing T
val p1 = new Processor[Int with SomeMix] {}
val ten = 10.asInstanceOf[Int with SomeMix]
p1.process(ten) //processing T with Mix
检查
答案 3 :(得分:1)
由于您已经提到,它肯定是T
的一个实例,因此您可以取消取消选中的警告:
case mix: (T @unchecked) with SomeMix
请注意,它仍然未被选中,并且在运行时仅测试匹配对象是SomeMix
的实例;如果您更改为例如
def process(t: Any) = ...
您会得到不好的结果。