2013-03-04 74 views
4

我声明了两个实用方法为implicit“参数化重载隐式方法不可视为视图边界”编译器警告的意思是什么?

class MyClass { ... } 
object MyClass { 
    implicit def finish: MyClass[Any,Nothing,Unit] = finish(()); 
    implicit def finish[R](result: R): MyClass[Any,Nothing,R] = ... 
} 

和我得到的编译器警告:

参数重载隐式方法是不可见的视图边界

这是什么警告意思?

+0

请发布代码nsippet,**不会**重现该问题,并指定您的Scala版本。 – 2013-03-04 08:45:16

+0

没关系,你的代码片段确实会产生警告,但只在** scala 2.9.x **(不再在Scala 2.10中)。 – 2013-03-04 08:52:48

回答

4

这里的“参数”确实应该“类型参数”。 或者在其他wods,警告说,因为你已经定义的隐式转换,既重载(有相同名称的其他方法),并通用,则该方法不能实际用作隐观,尽管它可以用来隐式地转换一个单纯的值。 我将设法示出了具有一个示例的区别:

class MyClass 
object MyClass { 
    implicit def finish: MyClass = null 
    implicit def finish[R](result: R): MyClass = null 
} 

val a: Int = 123 
val b: MyClass = a // Compiles fine: implicit conversion properly applied 

def foo[R<%MyClass](r: R) {} 
foo(123) // Error: No implicit view available from Int => Test.MyClass 

在上面的代码段中,a(的Int类型)隐式转换为MyClass,因此隐式转换按预期方式工作。

然而,最有趣的部分是与foo方法。它被视为与MyClass绑定。换句话说,您应该能够传递foo任何可隐含转换为MyClass的值。但是这里没有编译。这是编译器警告你的这个错误。 果然,如果你注释掉finish的第一超载(当一个不带一个类型参数),或使他们不超载重命名版本(比如你重命名为finish2其中之一),那么编译错误消失。

如果您想知道第一种情况(直接隐式转换)和第二种情况(调用具有视图边界的方法)之间的区别是什么,它们允许编译好而不是另一种,关键是一个视图边界需要传递一个隐式函数值。

事实上,

def foo[R<%MyClass](r: R) 

相同

def foo[R](r: R)(implicit conv: R => MyClass) 

所以调用foo时,编译器不仅需要找到合适的隐式转换,同时也促进了隐式转换方法(第二个finish重载)到一个函数实例,并将其隐式传递给foo

我认为,这是本次促销活动,编译器(出于某种原因)不知道如何在类型参数和重载方法的情况下做的。 这纯粹是猜测,但我敢肯定,这只是一个实现的限制:这将非常是可行的,但它会介绍,这是不认为足够重要,足以执行问题(毕竟,你可以通过只重命名修复隐式转换方法)。

作为边注,警告未在阶2发射(默认)。10(它被认为太吵了,在scala中使用了类的类型),但真正的问题仍然存在,并且foo的调用仍然无法编译。

相关问题