Создание рекурсивного значения в Scala - PullRequest
1 голос
/ 20 марта 2020

Мне дали следующий код Scala, представляющий рекурсивное значение:

class Cons(elem: Int, next: => Cons)
val x = new Cons(1, x)

Я получил пример, но я пытаюсь понять детали. В частности, что делает запись => Cons? Это не даст мне аргументов (юнитов), и я дам вам минусы?

Ответы [ 2 ]

3 голосов
/ 20 марта 2020

x не инициализируется до оценки new Cons(1, x), что означает, что до этого момента оно имеет значение null, однако x само по себе является аргументом для конструктора Cons. Если параметр объявлен по значению, то он оценивается до того, как передается. В этом случае new Cons(1, x) становится new Cons(1, null), что не то, что мы хотим. Вместо этого мы можем объявить параметр как по имени , используя запись =>, чтобы задержать оценку аргумента. Теперь new Cons(1, x) становится чем-то вроде

new Cons(1, () => x))

Это дает val x возможность правильно инициализироваться перед использованием.

По имени:

class Cons(elem: Int, next: => Cons) {
  def n = next
}
val x: Cons = new Cons(1, x)

x.n
// res0: Cons = Cons@f523e05

По стоимости

class Cons(elem: Int, next: Cons) {
  def n = next
}
val x: Cons = new Cons(1, x)

x.n
// res0: Cons = null
3 голосов
/ 20 марта 2020

Почти, это by-name параметр:

Параметры по имени оцениваются каждый раз, когда они используются. Они не будут оцениваться вообще, если они не используются. Это похоже на замену параметров по имени на переданные выражения. Они в отличие от параметров по значению. Чтобы создать параметр с именем by-name, просто добавьте => к его типу.

Он ведет себя как функция (на самом деле он скрыт), но вам не нужно приложение функции () читать это. Каждый раз, когда вы используете параметр, блок, который оценивает его, переоценивается.

Вы можете прочитать об этом здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...