简体   繁体   中英

Why does the toString method on scala.Function1 and scala.Function2 have parenthesis

I am implementing a derivation of (Int) => String) and overriding the toString method like this:

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

IDEA IntelliJ indicates the toString method is being overriden from Function1.toString (as does Scala IDE). And IntelliJ also shows the following warning indicating empty parenthesis must be added to the toString method due to the Function1.toString declaration including empty parenthesis (Scala IDE does NOT show this warning):

Empty-paren Scala method overridden as parameterless

The convention is that you include parentheses if the method has side effects. In accordance with Liskov substitution principle, as overriden method is empty-paren, the overriding method must also be declared as a method with side effects. * Refer to Programming in Scala, 5.3 Operators are methods

I then went to the ScalaDoc and checked Function1 ( source ), Function2 ( source ) and PartialFunction ( source ) in the scala package. In the source code for 2.11.2, Function1 and Function2 each overrides the toString method and includes empty parenthesis (and PartialFunction just uses Function1 's override). So, given both Function1 and Function2 declare a String literal for the toString method, I don't understand why the parenthesis would have been included in the source code for these two class files.

What obvious thing am I missing which justifies the use of parenthesis on the toString method? Or is the IntelliJ warning incorrect? Or if the IntelliJ warning is correct, why isn't the Scala IDE showing the same warning as IntelliJ?

override def f overriding def f() is assumed to have parens, by the spec.

The IntelliJ message you quote says there is a "convention" that you should include the parens to document that the method is not just an accessor but may have side-effects.

Not everyone agrees with or conforms to that notational "convention."

The convention is especially empty in the case of toString , since many toString methods are side-effecting, such as iterators initializing state.

I just asked this on the ML recently:

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

I answered my own question in the follow-up:

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

A special rule concerns parameterless methods. ... f is also assumed to have an empty parameter list.

Which means you can leave the parens off the overriding definition.

For example,

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

Yf has an empty param list.

Since Object.toString() has an empty param list, so does every override, including overrides of Any.toString .

(Java's toString() is cited as the reason parens are supplied, in the conversion called "Empty application".)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM