【发布时间】:2011-05-23 05:01:24
【问题描述】:
在TraversableOnce 中,有一个sum 方法只有在包含的类型为Numeric 时才可用(否则它不会编译)。我想知道这是否可用于其他情况(以避免运行时检查)。
特别是我们有两个特征 A 和 B 的情况。我们希望有一个方法 f 只能在对象继承 both 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
}
}
【问题讨论】:
-
您也可以使用
ev参数来避免强制转换——它是Function1[self.type, Foo]。更新了我的答案以进行演示。