Scala String toInt - Int не принимает параметры

Итак, я изучаю Scala, и я столкнулся с этой непростой проблемой...

Если у нас есть String и мы хотим преобразовать его в Int, все примеры, которые я нашел в Интернете, говорят: "Это так просто! Просто используйте String.toInt!"

Итак:

var x = readLine().toInt

Прост достаточно. Я предполагаю, что toInt является функцией String. Но если это так, я должен был бы назвать toInt круглыми скобками, верно? Исходя из Java, мне это кажется более естественным:

var x = readLine().toInt()

Но, увы! Scala дает мне следующую ошибку:

[error]/home/myhome/code/whatever/hello.scala:13: Int не принимает Параметры

[ошибка] var x = readLine(). toInt()

Любопытный. Что означает эта ошибка? Является toInt не функцией String? Аналогично, почему я могу сделать оба:

var x = readLine().toLowerCase()
var y = readLine().toLowerCase

без каких-либо проблем?

Изменить: Дублирующий вопрос не относится к проблеме toLowerCase vs toInt.

Ответы

Ответ 1

Это хороший вопрос, и я не думаю, что он считается дубликатом вопроса об определении методов нулевой последовательности с круглыми скобками или без них.

Разница между toInt и toLowerCase заключается в том, что toInt является синтаксическим обогащением, предоставляемым стандартным классом библиотеки StringOps. Вы можете проверить это, используя reify и showCode в REPL:

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

Это просто вызывает вызов метода обогащения и показывает вам, какое косвенное преобразование было применено для его поддержки.

Если мы посмотрим на toInt метод на StringOps, мы увидим, что он определен без круглых скобок. Поскольку вопрос о возможном дублирующем вопросе указывает на то, что если метод no-arity в 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), он попадает в эту категорию, что означает, что вы можете назвать его в любом случае.