Левша эквивалент apply в Scala

#scala #matrix #operator-overloading #operators

Вопрос:

Очень легко определить что-то вроде 2-мерного матричного класса в Scala с помощью метода apply, который позволил бы мне элегантно получить доступ к значениям внутри моей матрицы. Довольно просто можно было бы сделать это :

 class Matrix(val n: Int, val m: Int, val default: Double = 0) {  val data: Array[Array[Double]] = Array.fill(n, m)(default)  def apply(x: Int, y: Int): Double = data(x)(y) }  

Это позволяет мне получать доступ к элементам в моей матрице следующим образом :

 val matrix = new Matrix(3, 3) println(matrix(2, 2))  

Однако мне нужна возможность сделать обратное и фактически присвоить значения матрице, используя аналогичную нотацию. По сути, я хочу иметь возможность написать что-то подобное :

 matrix(2, 2) = 5  

Есть ли какой — нибудь способ сделать это в Scala ? В C это выполнимо путем перегрузки оператора скобок для возврата ссылки, а не копии (первый определяет установщик, а второй-получатель), и аналогично в Python это различие между методами __getitem__ и __setitem__ magic (с небольшой разницей в применении к квадратным скобкам вместо скобок). Поддерживает ли Scala такое поведение, или мне приходится либо напрямую обращаться к data члену и/или просто писать функцию настройки ?

Ответ №1:

Возьмем Array # update в качестве примера:

 /** Update the element at given index.  *  * Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`.  *  * @param i the index  * @param x the value to be written at index `i`  */  def update(i: Int, x: T): Unit  

Попробуйте реализовать update :

  class Matrix(val n: Int, val m: Int, val default: Double = 0) {  ...  def update(x:Int, y: Int, value: Double): Unit =  ??? }   matrix(2,2) = 5d  

ИЗМЕНИТЬ:
Вы действительно можете использовать:

  • def update(x:Int, y: Int, value: Double): Unit

вместо:

  • def update(coord: (Int,Int), value: Double): Unit .

и получите именно тот синтаксис, который вы хотели.

Комментарии:

1. Идеально ! Именно то, что я искал. Хотя у вас есть дополнительный набор скобок в последней строке 😉

2. С моим последним обновлением вы можете убрать лишнюю скобку

3. Да, это то, что я только что реализовал в своем коде. Еще раз спасибо ! Приятно видеть, что Scala поддерживает это напрямую.