Ну, это просто означает, что вы можете определить реферат val
def
и аннотация def
по val
.
Например
trait Server {
def port:Int
}
имеет абстрактную функцию, а именно port
. Вы можете точно реализовать (или определить или переопределить) это с def
, как этого
object DefaultServer extends Server {
override def port: Int = 80
}
Но в этом случае каждый доступ к port
будет вызывать функцию приложение (или вызов метода), который является просто ненужным. По этой простой причине Scala дает нам возможность реализации абстрактного def
со значением:
object DefaultServer extends Server {
override val port: Int = 80
}
То же самое относится к абстрактным ценностям. Вы можете определить абстрактные значения с тем же синтаксисом:
trait Server {
val port: Int
}
И вы можете переопределить их с def
:
object DefaultServer extends Server {
override def port: Int = 80
}
Устойчивость
Вы можете задаться вопросом, что произойдет, если вы переопределить abstract val
с def
, который дает вам другое значение каждый раз, когда вы его вызываете. Вы получите первое вычисленное значение, потому что элемент является val
или вы получите другое значение при каждом его вызове, потому что фактическая реализация - это def
.
Например:
object DefaultServer extends Server {
override def port: Int = scala.util.Random.nextInt()
}
К счастью Scala компилятор обнаруживает это и выдает следующее сообщение об ошибке:
error: overriding value a in trait Server of type Int;
method a needs to be a stable, immutable value
override def port:Int = scala.util.Random.nextInt()
лени
Когда дело доходит до лени это единообразное поведение (лечащий поля и методы таким же образом) очень полезно.
Прежде всего обратите внимание, что абстрактное значение не существует, то есть вы не можете определить абстрактный val
как lazy
.
Реализация абстрактного def
lazy val
, с другой стороны, является совершенно законной и полезной. Значение lazy
будет вычисляться только по первому вызову и сохранено в памяти (кэшировано и используется для будущих вызовов).
Я всегда получаю ошибку «метод должен быть стабильным, неизменным значением», когда я переопределяю val с def. –
Вы уверены, что это не когда вы переопределяете 'val' с' lazy val'? –
Нет, я копирую ваш пример кода. –