Подтвердить что ты не робот

Зачем использовать def и val в Scala или наоборот

Я знаю, что это обсуждалось на SO в других сообщениях раньше, и я понимаю основную разницу между использованием def и val. def используется для определения метода и val для неизменяемой ссылки. То, что я пытаюсь выполнить, задавая этот вопрос, заключается в том, чтобы понять, есть ли что-то большее для def. Может ли он использоваться взаимозаменяемо с val?

Недавно я попробовал следующий код и не могу убедить себя, достаточно ли моего нынешнего понимания def:

scala> def i: Int = 3
i: Int

scala> i
res2: Int = 3

Итак, мне интересно, это эквивалентно val i = 3?

Затем я попробовал это:

scala> i()
<console>:9: error: Int does not take parameters
i()

Я сделал это, чтобы проверить свое понимание семантики def. Теперь я хочу знать, когда i является методом, почему Scala жалуется на "... не принимает параметры"?

Далее я попробовал следующее:

scala> def i(): Int = 3
i: ()Int

scala> i()
res4: Int = 3

На этот раз Scala, похоже, согласен, что i является методом. Могу ли я использовать def вместо val взаимозаменяемого для объявления и инициализации переменной?

4b9b3361

Ответ 1

И

def i = 3

и

def i() = 3

объявить методы. Единственное отличие состоит в том, что первый - это метод без списка параметров, а второй - метод с пустым списком параметров. Первый обычно используется для методов без побочных эффектов, а второй для методов с побочными эффектами. Вы должны использовать val вместо def, если значение никогда не изменяется, и вы хотите избежать его пересчета. Def получает recomputed каждый раз, когда он вызывается, в то время как val присваивается значение только один раз.

Ответ 2

def определяет метод, val определяет неизменяемое значение, как вы уже знаете.

Одно существенное отличие заключается в том, что вычисляется выражение в правой части =. Для метода он оценивается каждый раз, когда вы вызываете метод. Для значения это оценивается при инициализации значения. См. Разницу:

scala> def i: Int = { println("Hello"); 3 }
i: Int

scala> i
Hello
res0: Int = 3

scala> i
Hello
res1: Int = 3

scala> val i: Int = { println("Hello"); 3 }
Hello
i: Int = 3

scala> i
res2: Int = 3

Ответ 3

Чтобы добавить в верхней части ответа Кима, вы можете переопределить def по val.

// Entering paste mode (ctrl-D to finish)

trait A {
def i: Int
def num: Long
}

class B extends A {
val i = 7
val num = 20L
}


// Exiting paste mode, now interpreting.

defined trait A
defined class B

scala> val b = new B
b: B = [email protected]

scala> b.i
res1: Int = 7

scala> b.num
res2: Long = 20