Scala curry在trait同伴对象中的应用
两个问题: 1) 为什么当Scala curry在trait同伴对象中的应用,scala,Scala,两个问题: 1) 为什么当apply函数是curry函数时,我不能在BaseTrait伴随对象中使用这两个apply方法(注意,当它们是非curry函数时,它会起作用,带有两个参数) 2) 我如何实现这一功能:多个套用的方法 trait BaseTrait[T, U] { def name: String def tryMe(record: T): Option[U] } object BaseTrait { // can't have both apply methods whe
apply
函数是curry函数时,我不能在BaseTrait
伴随对象中使用这两个apply
方法(注意,当它们是非curry函数时,它会起作用,带有两个参数)
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) }
scala>BaseTrait(“测试”){s:String=>Option(s.toBoolean)}
:13:错误:对重载定义的引用不明确,
这两种方法都适用于类型为[T](s:String)(f:T=>
选项[Boolean])布尔特征[T]
和方法应用于类型为[T](s:String)(f:T=>
选项[Long])LongTrait[T]
匹配参数类型(字符串)
BaseTrait(“test”){s:String=>Option(s.toBoolean)}
如果颠倒当前参数的顺序,使它们在第一个参数中有所不同,则可以成功调用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
如评论中所述。在被引用的问题中(该问题以“惯常修复”状态结束),下面的简单代码也显示了相同的模糊引用问题
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
根据Scala语言创作者Martin Odersky的说法
“我刚才在上面写道,规范中没有尝试做这样的事情。我向您提出挑战,请您提供一套完整且可确定的规则来完成此操作。”
因此,由于难以实施必要的检查,因此不可能阻止这些方法编译,即使它们随后无法被引用。我认为,它编译的是一个bug。这不应该。@Dima你能详细说明一下吗?Scala编译器是否能够区分b/w Function1[T,Option[Boolean]]和Function1[T,Option[Long]],但编译的Java代码却不能?如果你有更多的细节,我很好奇。谢谢你给我指出这个问题!遗憾的是没有解决方案(除了交换方法的第一部分)。