首页 文章

名为“*”的方法导致编译错误

提问于
浏览
1

我对此代码感到困惑:

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 回答

  • 3

    我倾向于认为问题在于 *Predef 重载到 String (如 "AA" * 5 ),因此,当你向它添加自己的 * 时,你会在转换中产生歧义,这会使Scala丢弃两者他们 .

    随着转换被丢弃,它仍然试图在 String 上找到 * ,而它不在那里 .

    这个想法的问题是 "AA" * 2 即使使用导入仍然有效,并且您添加的转换在没有隐式参数的情况下工作 . 但我仍然认为答案就是这样 .

相关问题