在TraversableOnce
中,有一个sum
方法只有在包含的类型是时才可用Numeric
(否则它不会编译)。我想知道这是否可用于其他情况(以避免运行时检查)。
特别是我们有两个特征 A 和 B 的情况。我们希望有一个方法f
,只有当对象继承 A 和 B 时才能使用。但如果它只扩展其中一个,则不能。我不想再做一个trait AB extends A with B
。f
如果不是两个特征都被继承,我只想无法使用。
package com.example
trait Base
trait Foo extends Base {
def g = println("foo bar " + toString)
}
trait Bar extends Base {
/* If this is both Foo and Bar, I can do more */
def f = {
if (!this.isInstanceOf[Foo]) error("this is not an instance of Foo")
this.asInstanceOf[Foo].g
}
}
object Test {
def main(args: Array[String]): Unit = {
object ab extends Foo with Bar
object ba extends Bar with Foo
object b extends Bar
ab.f
ba.f
// I don't want next line to compile:
try { b.f } catch { case e: RuntimeException => println(e) }
}
}
编辑:解决方案,感谢@Aaron Novstrup
trait Bar extends Base { self =>
def f(implicit ev: self.type <:< Foo) = {
//self.asInstanceOf[Foo].g // [1]
ev(this).g // [2]
}
}
现在在main
,b.f
不编译。好的
编辑 2:将第 [1] 行更改为 [2] 反映了@Aaron Novstrup 回答的变化
编辑 3:不使用self
@Aaron Novstrup 在答案中的反映变化
trait Bar extends Base {
/* If this is both Foo and Bar, I can do more */
def f(implicit ev: this.type <:< Foo) = {
ev(this).g
}
}