简体   繁体   English

什么“参数化重载隐式方法不可见为视图边界”编译器警告意味着什么?

[英]What does “parameterized overloaded implicit methods are not visible as view bounds” compiler warning mean?

I declared two utility methods as implicit 我声明了两个实用方法是implicit

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

and I'm getting compiler warnings: 我正在收到编译器警告:

parameterized overloaded implicit methods are not visible as view bounds 参数化重载的隐式方法作为视图边界不可见

What does this warning mean? 这个警告意味着什么?

Here "parameterized" should really be "type parameterized". 这里“参数化”应该是“类型参数化”。 Or in other wods, the warning says that because you have defined an implicit conversion that is both overloaded (there are other methods of the same name) and generic , then the method cannot actually be used as an implicit view, although it can be used to implicitly convert a mere value. 或者在其他方面,警告说因为你已经定义了一个隐式转换,它同时被重载 (有其他同名方法)和泛型 ,那么该方法实际上不能用作隐式视图,尽管它可以使用隐含地转换纯粹的价值。 I'll try to illustrate the difference with an example: 我将尝试用一个例子来说明差异:

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

In the above code snippet, a (of type Int ) is implicitly converted to MyClass , so the implicit conversion works as expected. 在上面的代码段中, a (类型的Int )的隐式转换为MyClass ,因此隐式转换按预期方式工作。

However, the interesting part is with the foo method. 然而,有趣的部分是foo方法。 It is declared with a view bound to MyClass . 它被声明为绑定到MyClass的视图。 In other words, you should be able to pass to foo any value that is implicitly convertible to MyClass . 换句话说,您应该能够将任何可隐式转换为MyClass值传递给foo But here it fails to compile. 但是这里无法编译。 This is this error that the compiler was warning you about. 这是编译器警告您的此错误。 And sure enough, if you comment out the first overload of finish (the one that does not take a type parameter), or rename a version so that they are not overloads (say you rename one of them to finish2 ), then the compile error goes away. 当然,如果你注释掉第一个finish重载(没有采用类型参数的那个),或者重命名一个版本以便它们不重载(比如你将其中一个重命名为finish2 ),那么编译错误消失了。

If you are wondering what is so different between the first case (direct implicit conversion) and the second one (call to method with a view bound) that would allow one to compile fine but not the other, the key point is that a view bound requires to pass a an implicit function value. 如果你想知道第一种情况(直接隐式转换)和第二种情况(带有视图绑定的方法调用)之间有什么不同,这将允许一个编译正常而不是另一个,关键点是视图绑定需要传递一个隐含的函数值。

Indeed, 确实,

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

is the same as 是相同的

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

So when calling foo , the compiler not only needs to find the appropriate implicit conversion, but also to promote the implicit conversion method (the second finish overload) to a function instance, and pass it implicitly to foo . 因此,在调用foo ,编译器不仅需要找到适当的隐式转换,还需要将隐式转换方法(第二次finish重载)提升为函数实例,并将其隐式传递给foo

I believe that this is this promotion that the compiler (for some reason) does not know how to do in the case of type parameterized and overloaded methods. 我相信这是促销,编译器(由于某种原因)在类型参数化和重载方法的情况下不知道如何做。 This is pure speculation but I am pretty sure that this is just an implementation limitation: this would very much be doable, but it would introduce enough implementation problems that it was not deemed important enough (after all you can fix it by just renaming the implicit conversion method). 这是纯粹的推测,但我很确定这只是一个实现限制:这非常可行,但它会引入足够的实现问题而不被认为是足够重要的(毕竟你可以通过重命名隐式修复它转换方法)。

As a side note, the warning is not emitted (by default) in scala 2.10 (it was deemed too noisy, with the surge of type class usage in scala), but the real problem remains, and the call to foo still fails to compile. 作为旁注,scala 2.10中没有发出警告(默认情况下)(它被认为太嘈杂,scala中类型类使用量激增),但真正的问题仍然存在,并且对foo的调用仍然无法编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 抑制 Scala 中的“参数化重载隐式方法作为视图边界不可见”警告 - Suppressing “parameterized overloaded implicit methods are not visible as view bounds” warning in Scala “覆盖隐含”是什么意思? - What does “override implicit” mean? 为什么 Scala 编译器不允许使用默认参数的重载方法? - Why does the Scala compiler disallow overloaded methods with default arguments? 使用“隐含请求”在Play中意味着什么? - What does using “implicit request” mean in Play? 限制组合隐式参数和视图/上下文范围的原因是什么? - What was the reason to restrict on combining implicit parameters and view/context bounds? 以下警告意味着什么:“不鼓励使用副作用的无效方法”? - What does the following warning mean: 'side-effecting nullary methods are discouraged'? 多个参数化类型是什么意思? - what does more than one Parameterized Types mean? 类型,元组,隐式优先级和重载方法 - Types, Tuples, Implicit priority and Overloaded methods 编译器无法解析带边界的隐式类型(有时) - compiler failure to resolve Implicit types with bounds (sometimes) Scala中的“非简单类型”警告意味着什么? - What does the “not a simple type” warning mean in Scala?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM