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