В Scala первичный конструктор класса не имеет явного тела, а определяется неявно из тела класса. Как тогда отличить поля от локальных значений (т.е. значений, локальных для метода конструктора)?
Например, возьмем следующий фрагмент кода, представляющий собой модифицированную форму примера кода из "Программирования на Scala":
class R(n: Int, d: Int) {
private val g = myfunc
val x = n / g
val y = d / g
}
Насколько я понимаю, это создаст класс с тремя полями: приватным "g" и публичными "x" и "y". Однако значение g используется только для вычисления полей x и y и не имеет никакого значения за пределами конструктора.
Итак, в этом (безусловно, искусственном) примере, как вы собираетесь определить локальные значения для этого конструктора?
Например.
class R(n: Int, d: Int) {
val (x, y) = {
val g = myfunc
(n/g, d/g)
}
}
Есть несколько способов сделать это. Вы можете объявить такие временные переменные внутри частных определений, которые будут использоваться во время конструирования. Можно использовать временные переменные внутри блоков, возвращающих выражения (как в ответе Alaz'). Или, наконец, вы можете использовать такие переменные внутри альтернативных конструкторов.
По аналогии с альтернативными конструкторами, вы также можете определить их внутри метода "apply" объекта-компаньона.
Что вы не можете сделать, так это объявить поле "временным".
Заметьте также, что любой параметр, полученный первичным конструктором, также является полем. Если вы не хотите, чтобы такие параметры становились полями, и не хотите раскрывать фактические поля в конструкторе, обычным решением будет сделать первичный конструктор приватным, с фактическими полями, и использовать либо альтернативный конструктор, либо объект-компаньон apply() в качестве эффективного "первичного" конструктора.
Другой вариант-сделать основной конструктор объекта частная и использовать компаньон объекта'ь применять метод в качестве строителя. Если мы применим (каламбур не предназначен) этот подход в вашем примере это будет выглядеть так:
class R private (val x: Int, val y: Int);
object R {
def apply(n: Int, d: Int): R = {
val g = myfunc;
new R(n / g, d / g);
}
}
Для создания экземпляра R вместо:
val r = new R(1, 2);
пишите:
val r = R(1, 2);
Это немного многословный, но могло быть и хуже, я думаю :). Позвольте's надеюсь, что частные[это] вальс будет рассматриваться как временные переменные в будущих выпусках Скала. Сам Мартин намекал, что.