Это хороший вопрос, и я не думаю, что он считается дубликатом question about defining zero-arity methods с круглыми скобками или без них.
Разница между toInt
и toLowerCase
здесь является то, что toInt
является синтаксическим обогащение, StringOps
класса из стандартной библиотеки. Вы можете проверить это с помощью reify
и showCode
в РЕПЛ:
scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}
scala> showCode(reify("1".toInt).tree)
res0: String = Predef.augmentString("1").toInt
Это просто desugars вызов метода обогащения и показывает, что неявное преобразование было применено, чтобы поддержать его.
Если мы посмотрим на toInt
method on StringOps
, мы увидим, что он определен без круглых скобок. Поскольку ответ на возможный дублирующий вопрос указывает на то, что если метод нулевой аргумента в Scala определен без круглых скобок, его нельзя вызывать с круглыми скобками (хотя, если он определен в круглых скобках, он может быть вызван в любом случае).
Так вот почему "1".toInt()
не работает. Если String
были обычным классом Scala, следующим нормальным соглашениям об именах Scala, "ABC".toLowerCase()
тоже не работал, поскольку метод был бы определен без круглых скобок, поскольку он не является побочным эффектом (это просто соглашение, но оно, как правило, довольно последовательно применяется в коде Scala).
Проблема в том, что String
на самом деле не класс в стандартной библиотеке Scala - это всего лишь java.lang.String
. На уровне JVM нет никакой разницы между методом с нулевой степенью, определенным с круглыми скобками, и одним без круглых скобок - это чисто различие Scala, и оно не кодируется в сигнатуре метода JVM, а в отдельной партии метаданных, хранящихся в файл класса.
Дизайнеры языка Scala решили обработать все методы нулевого уровня, которые не определены в Scala (и, следовательно, не имеют этих дополнительных метаданных), как если бы они были определены с круглыми скобками. Поскольку метод toLowerCase
на String
действительно и действительно является методом класса java.lang.String
(а не синтаксического метода обогащения, такого как toInt
), он попадает в эту категорию, что означает, что вы можете назвать его в любом случае.
Возможный дубликат [В чем разница между def foo = {} и def foo() = {} в Scala?] (Http://stackoverflow.com/questions/7409502/what-is-the-difference- между-def-foo-and-def-foo-in-scala) –