Как да получите семантика на 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