4

在 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 不要转换为隐式?

4

2 回答 2

3

我无法回答是否可以更改此行为,但我在规范中找到了以下描述(第 85 页):

赋值运算符被特殊对待,因为如果没有其他解释是有效的,它们可以扩展为赋值。让我们考虑一个赋值运算符,例如中缀运算 l += r 中的 +=,其中 l, r 是表达式。该操作可以重新解释为对应于赋值 l = l + r 的操作

据我了解,由于您提供了另一种解释,因此扩展不会发生。Myabe 这将有助于追踪问题。

于 2013-08-09T16:16:57.143 回答
3

另一个答案没有引用规范中的整个段落,这是明确的:

如果满足以下两个条件,则发生重新解释。1. 左侧 l 没有名为 += 的成员,也不能通过隐式转换(第 6.26 节)转换为具有名为 += 的成员的值。

(另一个条件是它会进行类型检查。)

当您使该类也隐式时,您已经定义了两个隐式转换(其中一个是 your toE),它们是模棱两可的并且被默默地忽略。(这是某种特征。)

所以你已经回答了你自己的问题:关闭隐式的一种方法是使其模棱两可。

另一种方法是隐藏名称,因为隐式必须通过其简单名称可用。

关于造成严重破坏:现在您知道为什么必须这样做了import scala.language.implicitConversions

我想你现在也知道 REPFL [原文如此] 中的 F--- 代表什么。

于 2013-08-09T16:30:08.503 回答