final class IntFactorialExtension(n: Int) {
final def ! = (1 to n) reduce (_ * _)
}
implicit def intFactorialExtension(n: Int) = new IntFactorialExtension(n)
5! //=> 120: Int
implicit class RichInt(n: Int) extends Ordered[Int] {
def min(m: Int): Int = if (n <= m) n else m
...
}
将由编译器进行如下转换:
class RichInt(n: Int) extends Ordered[Int] {
def min(m: Int): Int = if (n <= m) n else m
...
}
implicit final def RichInt(n: Int): RichInt = new RichInt(n)
2条答案
按热度按时间smdnsysy1#
可能会有名字冲突,因为
扩展到
所以如果还有别的
fooOps
范围中的定义,则可能导致名称冲突。从scala 3开始,这不再是一个问题,因为我们不必为隐式类命名,而只需编写
f87krz0w2#
作用域中可能没有与隐式类同名的方法、成员或对象。
只是想知道为什么会这样?
简单的回答是:因为它们是方法!
稍微长一点的答案是:因为隐式类是类和方法的语法糖。
还记得在隐式类出现之前我们写过什么吗:
斯卡斯蒂链接
如sip-13所定义 – 隐式类(链接自您引用的文档),隐式类只是一个方法(隐式转换)和一个类的语法糖,就像我们过去在隐式类之前手工编写的一样[粗体强调]:
隐式类必须在允许方法定义的范围内定义(不在顶层)。隐式类被分解为类和隐式方法对,其中隐式方法模仿类的构造函数。
生成的隐式方法将与隐式类具有相同的名称。这允许使用类的名称导入隐式转换,正如从其他隐式定义中所期望的那样。例如,形式的定义:
将由编译器进行如下转换:
因此,由于隐式类同时分解为类型域(类)中的名称和值域(方法/隐式转换)中的名称,因此它在类型域和值域中都必须合法有效,这对于隐式转换来说,特别意味着范围中的值域中不能有其他名称。