es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Equivalente para zurdos de apply en Scala.

Es muy fácil definir algo como una clase Matrix bidimensional en Scala con un método apply que me permitiría acceder elegante a los valores dentro de mi matriz. Básicamente, uno haría esto:

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)
}

Esto me permite acceder a los elementos de mi matriz así:

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

Sin embargo, lo que necesito es la capacidad de hacer lo contrario, es decir, asignar valores a una matriz utilizando una notación similar. Básicamente, quiero la capacidad de escribir algo como esto:

matrix(2, 2) = 5

¿Existe alguna forma de hacer esto en Scala? En C++ esto se puede hacer sobrecargando el operador de paréntesis para devolver una referencia en lugar de una copia (el primero define el setter y el segundo el getter), y de manera similar en Python esta es la distinción entre los métodos mágicos __getitem__ y __setitem__ (con la ligera diferencia de aplicarse a corchetes en lugar de paréntesis). ¿Scala admite dicho comportamiento o me quedaré atrapado teniendo que acceder directamente al miembro data y / o simplemente escribir una función setter?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible sobrecargar el operador paréntesis en Scala para permitir tanto obtener como establecer valores de una clase de Matriz. Esto se puede lograr definiendo un método update además del método 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)
    
      def update(x: Int, y: Int, value: Double): Unit = data(x)(y) = value
    }
    

    Con este cambio, ahora puede usar la clase de matriz de la siguiente manera:

    val matrix = new Matrix(3, 3)
    println(matrix(2, 2)) // imprime 0.0
    matrix(2, 2) = 5
    println(matrix(2, 2)) // imprime 5.0
    

    Tenga en cuenta que el método update está definido para tomar un argumento adicional value, que se utilizará para establecer el valor de la matriz en la ubicación especificada. Cuando usa la notación de paréntesis con una asignación (matrix(2, 2) = 5), el compilador llamará automáticamente al método update en lugar del método apply.

    Entonces, en conclusión, Scala admite efectivamente el comportamiento que busca, mediante la sobrecarga de métodos.

Comments are closed.