#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 поддерживает это напрямую.