Лучшая практика использования переменных экземпляра Scala - PullRequest
15 голосов
/ 31 января 2011

Как можно перевести следующий Java-код в Scala?

class ClassA {
    private int field1;
    private int field2;

    public ClassA() {
        field1 = 1;
        field2 = 2;
    }
}

Я вижу два варианта:

class ClassA(val field1: Int, val field2: Int) {
   ....
}

Или

class ClassA {
   val field1: Int = 1
   val field2: Int = 2
}

Что такоерекомендуется, а почему?

Ответы [ 5 ]

18 голосов
/ 31 января 2011

Нет простого перевода с Java на Scala, это зависит от контекста:

  • Переменные ли изменчивы в Java? Если да (иначе они должны быть окончательными в Java): имеет ли смысл сделать их неизменными в Scala?
  • Должен ли конструктор оставаться открытым в Scala? Будет фабрикой (например, метод применения в объект-компаньон) более подходящий?
  • Почему являются частными переменными? У них есть геттеры и / или сеттеры?
  • Когда нужны переменные, имеет ли смысл делать их ленивыми?
  • Если значения неизменны и доступны, будут ли они полезны при сопоставлении с образцом? Будет ли класс кейса правильным выбором?
  • Могут ли переменные быть сгруппированы (например, в кортеже) для упрощения API и доступа?

Понимаете, есть так много соображений. Я бы посоветовал узнать о возможностях Scala и поэкспериментировать с другими подходами, иначе вы застряли в ловушке «Scala как лучшая Java» дольше, чем нужно.

8 голосов
/ 31 января 2011

Это самый прямой перевод на Scala:

class ClassA{
  private var field1 = 1
  private var field2 = 2
}

Обратите внимание на использование var вместо val. val является неизменным полем, соответствующим public final в Java. Таким образом, его нельзя изменить позже, и важно предоставить способ инициализации такого поля правильным значением для данного экземпляра.

Чтобы решить, что вы хотите использовать, вы должны задать себе вопросы, перечисленные в ответе Ландея.

6 голосов
/ 31 января 2011

Самое большое различие между ними состоит в том, что параметр класса один можно использовать в качестве конструктора. Если вы хотите, чтобы конструктор не имел параметров, как ваш пример Java, вам нужно использовать второй, плюс добавить частный модификатор, как предложено @ Debilski.

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

class ClassA (private val field1: Int = 1, private val field2: Int = 2)

// Using defaults
val a = new ClassA

// Setting new values
val b = new ClassA(3, 4)
4 голосов
/ 31 января 2011

Если вы хотите иметь приватные поля, почему бы не объявить их закрытыми?

class ClassA {
  private val field1: Int = 1
  private val field2: Int = 2
}
1 голос
/ 31 января 2011

Если вы всегда хотите, чтобы field1 и field2 имели одинаковые значения для каждого экземпляра класса A, я бы предложил поместить их в сопутствующий модуль:

object A {
  private val field1 = 1
  private val field2 = 2
}

Изатем используйте их в классе A:

class A {
  def complexInternalComputation = 2*A.a
}

или так:

class A {
  import A._
  def complexInternalComputation = 2*a
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...