【问题标题】:scala abusive implicit conversionscala 滥用隐式转换
【发布时间】:2013-08-09 15:13:15
【问题描述】:
在 Scala 2.10 REPFL 中:
>
class E(val i: Int) { def += (other: E) = i - other.i }
implicit def toE(i: Int) = new E(i)
var j = 1
j += 3
结果:
res1: Int = -2
> j
j: Int = 1
请注意,与使用之前的转换方法相比,如果 E 类本身被标记为隐式,则不会干扰常规 +=。
哇,如果这个隐式转换在范围内,我已经能够彻底破坏程序了!如果含义已经存在,有没有办法让scala不要转换为隐含?
【问题讨论】:
标签:
scala
overriding
implicit-conversion
【解决方案1】:
我无法回答是否可以更改此行为,但我在规范 (p. 85) 中找到了以下描述:
赋值运算符被特殊对待,因为它们可以
扩展到分配如果没有其他解释是有效的。让我们
考虑一个赋值运算符,例如中缀运算 l += 中的 +=
r, 其中 l, r 是表达式。这个操作可以重新解释为
对应于赋值 l = l + r
的操作
据我了解,由于您提供了另一种解释,因此扩展不会发生。 Myabe 这将有助于追查问题。
【解决方案2】:
另一个答案没有引用规范中的整个段落,这是明确的:
如果满足以下两个条件,就会发生重新解释
履行。
1. 左侧 l 没有名为 += 的成员,也不能通过隐式转换(第 6.26 节)转换为具有
一个名叫
+=。
(另一个条件是类型检查。)
当您将类设为隐式时,您已经定义了两个隐式转换(其中一个是您的toE),它们是模棱两可的并且被默默地忽略。 (这是某种特征。)
所以你已经回答了你自己的问题:关闭隐式的一种方法是使其模棱两可。
另一种方法是隐藏名称,因为隐式必须通过其简单名称可用。
关于造成严重破坏:现在您知道为什么必须import scala.language.implicitConversions。
我想你现在也知道 REPFL [原文如此] 中的 F--- 代表什么。