【问题标题】:Method named "*" cause compile error名为“*”的方法导致编译错误
【发布时间】:2012-12-31 14:48:36
【问题描述】:

我对这段代码有点困惑:

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: error: value * is not a member of 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"
}

顺便说一句,如果我们删除 'implicit 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"
}

* 是否具有比隐式参数更高的优先级,但 / 具有更低的优先级?还是有其他原因 * 在这种情况下不起作用?

【问题讨论】:

  • 如果 Daniel C. Sobrals 的评论是正确的,您可以考虑将操作符命名为“:*”。看起来不太好,但确实可以。

标签: scala operator-keyword operator-precedence


【解决方案1】:

我倾向于认为问题在于*Predef 重载为String(如"AA" * 5),因此,当您向其中添加自己的* 时,您会在转换中遇到歧义,从而使 Scala 放弃它们。

放弃转换后,它会尝试在String 上找到*,但它不存在。

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

【讨论】:

  • -Yinfer-debug 似乎说隐式 int 参数破坏了您从视图 T
猜你喜欢
  • 2021-11-28
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 2015-09-12
  • 1970-01-01
相关资源
最近更新 更多