我对此代码感到困惑:
abstract class Abstract3 {
type TP
protected def action(arg: TP): TP
def *[T <% TP](arg: T) = action(arg)
}
class Concrete3(str: String) extends Abstract3 {
type TP = Concrete3
override protected def action(arg: TP) = new TP("")
}
class Test3 {
implicit def str2Concrete(s: String)(implicit num: Int) = new Concrete3(s)
implicit val a = 1
val foo = "AA" * "BB" * "CC"
}
Scala编译器无法编译它,并显示错误消息:
test.scala:15:错误:值不是String的成员val foo =“AA”“BB”*“CC”^发现一个错误
但是如果我们将''*''改为'/'或其他任何东西,它将成功编译:
abstract class Abstract3 {
type TP
protected def action(arg: TP): TP
def /[T <% TP](arg: T) = action(arg)
}
class Concrete3(str: String) extends Abstract3 {
type TP = Concrete3
override protected def action(arg: TP) = new TP("")
}
class Test3 {
implicit def str2Concrete(s: String)(implicit num: Int) = new Concrete3(s)
implicit val a = 1
val foo = "AA" / "BB" / "CC"
}
顺便说一句,如果我们删除'隐藏num:Int',它也会编译好 .
abstract class Abstract3 {
type TP
protected def action(arg: TP): TP
def *[T <% TP](arg: T) = action(arg)
}
class Concrete3(str: String) extends Abstract3 {
type TP = Concrete3
override protected def action(arg: TP) = new TP("")
}
class Test3 {
implicit def str2Concrete(s: String) = new Concrete3(s)
val foo = "AA" * "BB" * "CC"
}
优先级高于隐式参数,但/优先级较低?或者还有其他原因在这种情况下*不起作用?
1 回答
我倾向于认为问题在于
*
被Predef
重载到String
(如"AA" * 5
),因此,当你向它添加自己的*
时,你会在转换中产生歧义,这会使Scala丢弃两者他们 .随着转换被丢弃,它仍然试图在
String
上找到*
,而它不在那里 .这个想法的问题是
"AA" * 2
即使使用导入仍然有效,并且您添加的转换在没有隐式参数的情况下工作 . 但我仍然认为答案就是这样 .