Как получить семантику Ponter/Reference в Scala

В C++ я бы просто взял указатель (или ссылку) на arr[idx].
В Scala я обнаружил, что создаю этот класс для эмуляции семантики указателя.

class SetTo (val arr : Array[Double], val idx : Int) {
  def apply (d : Double) { arr(idx) = d }
}

Нет ли более простого способа?
Разве в классе Array нет метода для возврата какой-либо ссылки на конкретное поле?


person Łukasz Lew    schedule 09.05.2010    source источник


Ответы (1)


Массивы, используемые в Scala, представляют собой массивы JVM (в версии 2.8), а массивы JVM не имеют концепции ссылки на слот.

Лучшее, что вы можете сделать, это то, что вы иллюстрируете. Но SetTo не кажется мне хорошим именем. ArraySlot, ArrayElement или ArrayRef кажутся лучше.

Кроме того, вы можете реализовать apply() для чтения слота и update(newValue) для замены слота. Таким образом, экземпляры этого класса можно использовать в левой части присваивания. Однако как для получения значения с помощью apply, так и для его замены с помощью метода update потребуются пустые списки аргументов, ().

class ASlot[T](a: Array[T], slot: Int) {
  def apply(): T = a(slot);
  def update(newValue: T): Unit = a(slot) = newValue
}

scala> val a1 = Array(1, 2, 3)
a1: Array[Int] = Array(1, 2, 3)

scala> val as1 = new ASlot(a1, 1)
as1: ASlot[Int] = ASlot@e6c6d7

scala> as1()
res0: Int = 2

scala> as1() = 100

scala> as1()
res1: Int = 100

scala> a1
res2: Array[Int] = Array(1, 100, 3)
person Randall Schulz    schedule 09.05.2010
comment
Нет ли по умолчанию mutable.SeqRef или чего-то в этом роде? Действительно? Разве мы не должны добавить его в стандартную библиотеку? Я предполагаю, что он мог бы использовать mutable.Seq вместо Array. - person Łukasz Lew; 10.05.2010
comment
@Alexy: Это, вероятно, лучше с точки зрения удобочитаемости. Мне пришло в голову, что неявное преобразование можно использовать и для считывания значения из указанного слота массива. - person Randall Schulz; 10.05.2010