两个问题:
1)当apply
函数被咖喱时,为什么我无法在BaseTrait
伴随对象中使用这两个apply
方法(请注意,它们在没有咖喱时会起作用,有两个参数)?
2)如何实现此功能:多个应用方法??
trait BaseTrait[T, U] {
def name: String
def tryMe(record: T): Option[U]
}
object BaseTrait {
// can't have both apply methods when curried
def apply[T](s: String)(f: T => Option[Long]): LongTrait[T] =
new LongTrait[T] {
override val name: String = s
override def tryMe(record: T): Option[Long] = f(record)
}
def apply[T](s: String)(f: T => Option[Boolean]): BooleanTrait[T] =
new BooleanTrait[T] {
override val name: String = s
override def tryMe(record: T): Option[Boolean] = f(record)
}
}
trait LongTrait[T] extends BaseTrait[T, Long] {
override def tryMe(record: T): Option[Long]
}
trait BooleanTrait[T] extends BaseTrait[T, Boolean] {
override def tryMe(record: T): Option[Boolean]
}
它编译得很好,但会引发运行时错误:
scala> BaseTrait("test") { s: String => Option(s.toBoolean) }
<console>:13: error: ambiguous reference to overloaded definition,
both method apply in object BaseTrait of type [T](s: String)(f: T =>
Option[Boolean])BooleanTrait[T]
and method apply in object BaseTrait of type [T](s: String)(f: T =>
Option[Long])LongTrait[T]
match argument types (String)
BaseTrait("test") { s: String => Option(s.toBoolean) }
答案 0 :(得分:3)
如果颠倒当前参数的顺序,使它们在第一个参数中不同,则可以成功调用apply方法。
object BaseTrait {
// can't have both apply methods when curried
def apply[T](f: T => Option[Long])(s: String): LongTrait[T] =
new LongTrait[T] {
override val name: String = s
override def tryMe(record: T): Option[Long] = f(record)
}
def apply[T](f: T => Option[Boolean])(s:String): BooleanTrait[T] =
new BooleanTrait[T] {
override val name: String = s
override def tryMe(record: T): Option[Boolean] = f(record)
}
}
BaseTrait { s:String => Option(s.toBoolean) }("test")
res58: BooleanTrait[String] = ammonite.$sess.cmd57$BaseTrait$$anon$2@e39317d
如评论中所述,this appears to be a corner case in the language。在引用的问题中,以Wont-Fix状态关闭,以下更简单的代码也表现出相同的模糊引用问题。
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
根据Scala语言创建者Martin Odersky所说,
&#34;我刚刚在上面写道,没有尝试在规范中做这样的事情。我要求你提供一套完整且可判定的规则来实现这一目标。&#34;
因此,由于难以实施必要的检查,即使无法随后引用这些方法,也无法阻止这些方法的编制。