В Scala, как Вы определяете локальный параметр в основном конструкторе класса?

нет ли способа подавить от предупреждений php.ini и ошибок? в этом случае можно отладить только изменение флага и не попытку к обнаружению, которое скрывает проблему.

8
задан Sampson 6 February 2012 в 17:14
поделиться

4 ответа

Если вы удалите ключевое слово «var» или «val» из параметра конструктора, оно не создаст свойства.

Однако имейте в виду, что non-var, non-val параметры конструктора входят в область видимости и доступны для всего класса. Если вы используете его в коде, не являющемся конструктором (т. Е. В теле метода), в сгенерированном классе будет невидимое закрытое поле, которое содержит этот параметр конструктора, как если бы вы сделали его «частной переменной» или private val "параметр конструктора.

Дополнение (лучше поздно, чем никогда ??):

В этом коде ссылки на параметр конструктора встречаются только в теле конструктора:

class C1(i: Int) {
  val iSquared = i * i
  val iCubed = iSquared * i
  val iEven = i - i % 2
}

... Здесь значение i существует только во время выполнения конструктора.

Однако в следующем коде поскольку на параметр конструктора имеется ссылка в теле метода, которое не является частью тела конструктора, параметр конструктора должен быть скопирован в (частное) поле сгенерированного класса (увеличивая его требования к памяти на 4 байта, необходимые для хранения Int ):

class C2(i: Int) {
  val iSquared = i * i
  val iCubed = iSquared * i
  val iEven = i - i % 2

  def mod(d: Int) = i % d
}
16
ответ дан 5 December 2019 в 06:09
поделиться

Вы можете создавать временные переменные во время инициализации отдельных членов класса следующим образом:

class A(b:Int){
  val m = {
    val tmp = b*b
    tmp+tmp
  }
}
4
ответ дан 5 December 2019 в 06:09
поделиться

Дерек,

Если у вас есть это:

class A(a: Int) {
  val aa = a // reference to constructor argument in constructor code (no problem)
  def m: Float = a.toFloat // reference to constructor argument in method body (causes a to be held in a field)
}

вы обнаружите (например, с помощью javap), что в классе присутствует поле с именем «a». Если вы закомментируете «def m», то увидите, что поле не создано.

3
ответ дан 5 December 2019 в 06:09
поделиться

После некоторых экспериментов я определил, что просто опуская var или val перед параметром b сделает его локальным параметром, а не элементом данных:

class A(var a: Int)
class B(b: Int) extends A(b)

Расширение Java:

$ javap -private B
Compiled from "construct.scala"
public class B extends A implements scala.ScalaObject{
    public B(int);
}

$ javap -private A
Compiled from "construct.scala"
public class A extends java.lang.Object implements scala.ScalaObject{
    private int a;
    public A(int);
    public void a_$eq(int);
    public int a();
    public int $tag()       throws java.rmi.RemoteException;
}

Обратите внимание, что класс A имеет частный член данных a из-за var a: Int в своем основном конструкторе. Однако класс B не имеет элементов данных, но его основной конструктор по-прежнему имеет единственный целочисленный параметр.

$ javap -private B
Compiled from "construct.scala"
public class B extends A implements scala.ScalaObject{
    public B(int);
}

$ javap -private A
Compiled from "construct.scala"
public class A extends java.lang.Object implements scala.ScalaObject{
    private int a;
    public A(int);
    public void a_$eq(int);
    public int a();
    public int $tag()       throws java.rmi.RemoteException;
}

Обратите внимание, что класс A имеет частный член данных a из-за var a: Int в его основном конструкторе. Однако класс B не имеет элементов данных, но его основной конструктор по-прежнему имеет единственный целочисленный параметр.

$ javap -private B
Compiled from "construct.scala"
public class B extends A implements scala.ScalaObject{
    public B(int);
}

$ javap -private A
Compiled from "construct.scala"
public class A extends java.lang.Object implements scala.ScalaObject{
    private int a;
    public A(int);
    public void a_$eq(int);
    public int a();
    public int $tag()       throws java.rmi.RemoteException;
}

Обратите внимание, что класс A имеет частный член данных a из-за var a: Int в его основном конструкторе. Однако класс B не имеет элементов данных, но его основной конструктор по-прежнему имеет единственный целочисленный параметр.

4
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: