左手等效于 Scala 中的 apply

Posted

技术标签:

【中文标题】左手等效于 Scala 中的 apply【英文标题】:Left handed equivalent of apply in Scala 【发布时间】:2022-01-08 20:11:38 【问题描述】:

使用 apply 方法在 Scala 中定义二维矩阵类之类的东西非常容易,它可以让我优雅地访问矩阵中的值。很简单,一个人会这样做:

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++ 中,这可以通过重载括号运算符以返回引用而不是副本来实现(前者定义 setter,后者定义 getter),类似地,在 Python 中,这是 __getitem____setitem__ 魔术方法之间的区别(与应用方括号而不是括号略有不同)。 Scala 是否支持这种行为,还是我不得不直接访问 data 成员和/或只编写一个 setter 函数?

【问题讨论】:

【参考方案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

得到你想要的语法。

【讨论】:

完美!正是我想要的。虽然你的最后一行有一组额外的括号;) 在我上次的更新中,你可以去掉多余的括号 是的,这就是我刚刚在我的代码中实现的。再次感谢 !很高兴看到 Scala 直接支持这一点。

以上是关于左手等效于 Scala 中的 apply的主要内容,如果未能解决你的问题,请参考以下文章

pyspark 等效于 Scala API 中的标志“isLocal”

Scala--Apply

等效于 Scala Dataset#transform 方法的 Pyspark 转换方法

Scala中apply的用法

什么是Scala等效于Java构建器模式?

Scala中的列表和元组