代码之家  ›  专栏  ›  技术社区  ›  Thomas

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

  •  0
  • Thomas  · 技术社区  · 5 年前

    作为隐式类命名。

    https://docs.scala-lang.org/overviews/core/implicit-classes.html

    只是想知道为什么会这样?我知道普通类可以有伴生对象,为什么不隐式对象呢?是因为和我一样的原因吗 here

    1 回复  |  直到 5 年前
        1
  •  2
  •   Mario Galic    5 年前

    可能会有名字冲突,因为

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

    扩展到

    fooOps(v).extensionMethod1()
    

    所以如果还有别的 fooOps

    从Scala 3开始这不再是个问题,因为我们有 not 我们必须为隐式类命名,而不是编写

    extension (v: TypeWeWantToAddExtensionTo) 
      def extensionMethod1() = ???
      def extensionMethod2() = ???
      ...
    
        2
  •  3
  •   Jörg W Mittag    5 年前

    作为隐式类命名。

    简单的回答是:因为他们 方法!

    稍微长一点的答案是:因为隐式类是类和方法的语法糖。

    final class IntFactorialExtension(n: Int) {
      final def ! = (1 to n) reduce (_ * _)
    }
    
    implicit def intFactorialExtension(n: Int) = new IntFactorialExtension(n)
    
    5! //=> 120: Int
    

    Scastie link

    SIP-13 – Implicit classes (链接自您引用的文档),隐式类只是方法(隐式转换)和类的语法糖,就像我们以前在隐式类之前手工编写的一样[ [我的]:

    隐式类 必须在允许方法定义的范围内定义 (不在顶层)。隐式类是 分解成类和隐式方法对 ,其中隐式方法模拟类的构造函数。

    这个 . 这允许使用类的名称导入隐式转换,正如从其他隐式定义中所期望的那样。例如,形式的定义:

    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)
    

    类型域 价值领域 (方法/隐式转换),它必须在类型域和值域中都合法有效,这对于隐式转换特别意味着范围中的值域中不能有其他名称。

    推荐文章