scala—为什么作用域中不能有与隐式类同名的方法、成员或对象

7eumitmz  于 2021-07-14  发布在  Java
关注(0)|答案(2)|浏览(236)

作用域中可能没有与隐式类同名的方法、成员或对象。
https://docs.scala-lang.org/overviews/core/implicit-classes.html
只是想知道为什么会这样?我知道普通类可以有伴生对象,为什么不隐式对象呢?是因为和这里一样的原因吗

smdnsysy

smdnsysy1#

可能会有名字冲突,因为

implicit class fooOps(v: TypeWeWantToAddExtensionTo) extends AnyVal {
  def extensionMethod1() = ???
}

val v: TypeWeWantToAddExtensionTo = ???
v.extensionMethod1()

扩展到

fooOps(v).extensionMethod1()

所以如果还有别的 fooOps 范围中的定义,则可能导致名称冲突。
从scala 3开始,这不再是一个问题,因为我们不必为隐式类命名,而只需编写

extension (v: TypeWeWantToAddExtensionTo) 
  def extensionMethod1() = ???
  def extensionMethod2() = ???
  ...
f87krz0w

f87krz0w2#

作用域中可能没有与隐式类同名的方法、成员或对象。
只是想知道为什么会这样?
简单的回答是:因为它们是方法!
稍微长一点的答案是:因为隐式类是类和方法的语法糖。
还记得在隐式类出现之前我们写过什么吗:

final class IntFactorialExtension(n: Int) {
  final def ! = (1 to n) reduce (_ * _)
}

implicit def intFactorialExtension(n: Int) = new IntFactorialExtension(n)

5! //=> 120: Int

斯卡斯蒂链接
如sip-13所定义 – 隐式类(链接自您引用的文档),隐式类只是一个方法(隐式转换)和一个类的语法糖,就像我们过去在隐式类之前手工编写的一样[粗体强调]:
隐式类必须在允许方法定义的范围内定义(不在顶层)。隐式类被分解为类和隐式方法对,其中隐式方法模仿类的构造函数。
生成的隐式方法将与隐式类具有相同的名称。这允许使用类的名称导入隐式转换,正如从其他隐式定义中所期望的那样。例如,形式的定义:

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)

因此,由于隐式类同时分解为类型域(类)中的名称和值域(方法/隐式转换)中的名称,因此它在类型域和值域中都必须合法有效,这对于隐式转换来说,特别意味着范围中的值域中不能有其他名称。

相关问题