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

为什么scala.Function1和scala.Function2上的toString方法有括号

  •  0
  • chaotic3quilibrium  · 技术社区  · 10 年前

    我正在实现 (Int) => String) 并覆盖 toString 方法如下:

    object A extends ((Int) => String) {
      override def toString: String = "A"
      def apply(int: Int): String = int.toString
    }
    

    IDEA IntelliJ表示 到字符串 正在从重写方法 Function1.toString (Scala IDE也是如此)。IntelliJ还显示以下警告,指示必须将空括号添加到 到字符串 由于 函数1.字符串 包含空括号的声明(Scala IDE不显示此警告):

    空paren Scala方法被重写为无参数

    惯例是,如果方法有边,则包含括号 影响。根据Liskov替代原则 overriden方法为空paren,重写方法也必须为 声明为具有副作用的方法。*参见中的编程 Scala,5.3运算符是方法

    然后我去ScalaDoc查看 Function1 ( source ), Function2 ( source )以及 PartialFunction ( source )在scala包中。在2.11.2的源代码中, Function1 Function2 每个都覆盖 到字符串 方法并包含空括号(和 PartialFunction 仅使用 功能1 的覆盖)。所以,考虑到两者 功能1 功能2 声明 String 的文字 到字符串 方法,我不明白为什么括号会包含在这两个类文件的源代码中。

    我缺少什么明显的东西来证明在 到字符串 方法或者IntelliJ警告不正确?或者,如果IntelliJ警告是正确的,为什么Scala IDE没有显示IntelliJ警告?

    1 回复  |  直到 10 年前
        1
  •  1
  •   som-snytt    10 年前

    override def f 最重要的 def f() 根据规范,假定具有父级。

    你引用的IntelliJ消息说,有一个“惯例”,你应该包括括号,以证明该方法不仅是一个访问器,而且可能有副作用。

    并不是所有人都同意或遵守这种符号化的“惯例”

    在以下情况下,公约尤其空洞 toString ,因为很多 到字符串 方法是有副作用的,例如迭代器初始化状态。

    我最近在ML上问过这个问题:

    https://groups.google.com/d/msg/scala-internals/ahNPTB6-P3M/1pPyptaH6coJ

    我回答了我自己的问题:

    http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#overriding
    

    一个特殊的规则涉及无参数方法。。。也假设f 参数列表为空。

    这意味着可以不使用替代定义的括号。

    例如

    scala> def f = 42
    f: Int
    
    scala> f()
    <console>:9: error: Int does not take parameters
                  f()
                   ^
    
    scala> class X { def f() = 42 }
    defined class X
    
    scala> class Y extends X { override def f = 43 }
    defined class Y
    
    scala> new Y().f()
    res1: Int = 43
    

    Y.f 具有空参数列表。

    自从 Object.toString() 有一个空的参数列表,每个重写也是如此,包括的重写 Any.toString .

    (Java的 toString() 在名为“空应用程序”的转换中,引用为提供括号的原因。)