2016-01-22 26 views
13

隐式转换下面的代码不编译:Scala中从母体性状

import scala.language.implicitConversions 

trait Base { 
    class Wrp[+T](val v: T) // wrapper/internal representation 
} 

trait BooleanOps extends Base { 
    // implicit conversion 
    implicit def lift2BooleanOpsCls(x: Boolean): BooleanOpsCls = 
    new BooleanOpsCls(new Wrp[Boolean](x)) 
    class BooleanOpsCls(wx: Wrp[Boolean]) { 
    def ||(wy: =>Wrp[Boolean]): Wrp[Boolean] = new Wrp[Boolean](wx.v || wy.v) 
    } 
} 

trait MyExample extends BooleanOps { 
    // test method 
    def foo(): Wrp[Boolean] = { 
    val ret: Wrp[Boolean] = false || new Wrp[Boolean](true) 
    ret 
    } 
} 

输出:

MyExample.scala:18: error: type mismatch; 
found : MyExample.this.Wrp[Boolean] 
required: Boolean 
     val ret: Wrp[Boolean] = false || new Wrp[Boolean](true) 
             ^

但如果I:

1)把class Wrp外侧基底

2)将BooleanOps的主体移动到MyExample

一切都编译完成。

为什么原始示例没有工作?如果您对此行为有一些了解,请注意帮助。谢谢。

回答

1

如果您重命名||方法,原始示例将起作用。编译器找到false.||()方法,并且不费心寻找可能在那里工作的隐式。

+0

确实,这个工作,但我想重载'||'操作符的行为。 编译器找到具有相同名称('||')的方法,但参数类型不同('Wrp [Boolean]'而不是'Boolean'),所以它应该执行隐式搜索。如果我将隐式转换放在MyExample的主体中,或者如果我把'class Wrp'定义放在Base的外部,就会发生这种情况,正如问题中指定的那样。我不明白为什么这些解决方案有效,而最初的例子没有。 – perovic

5

的一个问题是在def ||(wy: =>Wrp[Boolean])
参数的呼叫按姓名性质,如果你把它rewite到def ||(wy: Wrp[Boolean])它的工作原理

,但我同意这是奇怪的是,如果你走动WRP或工作BooleanOpsCls!隐含分辨率的意图或错误?

+0

太棒了,我可以证实这是有效的。谢谢:) 问题仍然是原始示例中发生的情况,也与提出的两种解决方法有关。 – perovic

+1

@perovic只是在@cbastin的背景下的想法回答:我认为,由于名称参数的性质隐式搜索是不同的,因为'=> Wrp [布尔]'是一个代码块,而不是类型。由于该编译器不认为此方法定义适用于隐式搜索。不幸的是,我不能确定这是否有任何可靠的来源,所以这是一个完全疯狂的猜测。但考虑到行为是奇怪的,并且依赖于'Wrp'定位,它看起来像一个bug,我想它值得作为编译器团队的jira票据发布吗? – Archeg

+0

@Archeg谢谢你的建议。看起来许多元素和规则是相互作用的。我仍然不确定这是一个错误,所以我会等一会儿,希望有人能够给出一个完整的解释。 – perovic

1

的问题是,有一个名为Wrp没有单一类(忽略T了一会儿) - Base没有定义Wrp而是定义每个具体类,它扩展Base的指定的子类。暗示也是一种红鲱鱼。提供的错误是提及MyExample.this.Wrp - 请记住,即使MyExample - val x = new MyExample的类型为Object with MyExample,也没有此类。

+0

谢谢你的回答Rob。在实际的代码中'Wrp'是一个抽象类型,我在这里简化了它。但是,如果'||'运算符的'Wrp [Boolean]'参数是按值调用,或者如果我在MyExample特性中隐式转换(隐式def和'class') 。你知道这与你的回答有什么关系吗? – perovic

+0

我不确定...也许你可以添加一个额外的替代最小例子? –