将赋值语法的去糖化为update
映射的调用将赋值 LHS 上的单个参数列表与赋值 RHS 上的值连接到方法定义的第一个参数块,而不管该方法update
有多少其他参数块update
定义有。虽然这种转换在某种意义上将单个参数块拆分为两个(一个在 LHS,一个在分配的 RHS),但它不会以您想要的方式进一步拆分左侧参数块。
我还认为您对显示的显式调用示例有误update
。update
这与您给出的定义不符,
scala> class Matrix { def update(i: Int, j: Int, value: Int) = (i, j, value) }
defined class Matrix
scala> val m = new Matrix
m: Matrix = Matrix@37176bc4
scala> m.update(1)(2)(3)
<console>:10: error: not enough arguments for method update: (i: Int, j: Int, value: Int)(Int, Int, Int).
Unspecified value parameters j, value.
m.update(1)(2)(3)
^
我怀疑在您的实验过程中,您实际上是这样定义更新的,
scala> class Matrix { def update(i: Int)(j: Int)(value: Int) = (i, j, value) }
defined class Matrix
更新去糖确实适用于这个定义,但可能不是您期望的方式:如上所述,它仅适用于第一个参数列表,这会导致类似的结构,
scala> val m = new Matrix
m: Matrix = Matrix@39741f43
scala> (m() = 1)(2)(3)
res0: (Int, Int, Int) = (1,2,3)
在这里,初始的单位参数块被拆分为赋值的 LHS 上的一个空参数块(即()
)和 RHS 上的一个单参数参数块(即1
)。然后是原始定义中的其余参数块。
如果你对这种行为感到惊讶,你不会是第一个。
您所追求的语法可以通过稍微不同的途径实现,
scala> class Matrix {
| class MatrixAux(i : Int) {
| def apply(j : Int) = 23
| def update(j: Int, value: Int) = (i, j, value)
| }
|
| def apply(i: Int) = new MatrixAux(i)
| }
defined class Matrix
scala> val m = new Matrix
m: Matrix = Matrix@3af30087
scala> m(1)(2) // invokes MatrixAux.apply
res0: Int = 23
scala> m(1)(2) = 3 // invokes MatrixAux.update
res1: (Int, Int, Int) = (1,2,3)