假设我有类型A
,B
和C
以及重载方法:
def foo(a: A): C
def foo(b: B): C
然后假设我有一个(复杂的)代码片段,它适用于C
类型的对象。我想要的是一种采用A
或B
类型的方法:
def bar(x: [A or B]) = {
val c = foo(x)
// Code that works with c
}
当然,我可以编写两个版本的bar
,重载以获取类型A
和B
,但在这种情况下,有多个函数的行为类似于bar
,对于所有这些版本,重载版本(在我的实际情况下,有foo
的三个版本)是愚蠢的。
C风格的宏在这里会很完美,所以我想看看Scala宏。尴尬的部分是Scala宏仍然是经过类型检查的,所以我不能说
reify(foo(x.splice))
因为编译器想要事先知道x
的类型。我是使用Scala宏的全新手段(而且它是一个实质性的API),所以在这方面的一些指示将不胜感激。
或者,如果有一种方法可以在没有宏的情况下布置此代码,那也会有所帮助!
答案 0 :(得分:1)
您可以采用不同的方式解决问题。
而不是说A or B
类型,而不是从这些类型中想出你想要什么。在你的例子中,如果你说:“只要我有一个foo
方法,它就是什么类型并不重要”。这就是下面的代码所示:
trait FooMethod[T] {
def apply(t:T):C
}
object FooMethod {
implicit val forA = new FooMethod[A] {
def apply(a:A):C = foo(a)
}
implicit val forB = new FooMethod[B] {
def apply(b:B):C = foo(b)
}
}
def bar[X](x: X)(implicit foo:FooMethod[X]) = {
val c = foo(x)
// Code that works with c
}