2015-04-05 117 views
4

刚开始用Nim语言编写(到目前为止我非常喜欢)。作为一个学习练习,我正在写一个小型矩阵库。我有更多的代码,但我只会显示与此问题相关的部分。Nim操作符重载

type 
    Matrix*[T; nrows, ncols: static[int]] = array[0 .. (nrows * ncols - 1), T]   

# Get the index in the flattened array corresponding 
# to row r and column c in the matrix 
proc index(mat: Matrix, r, c: int): int = 
    result = r * mat.ncols + c 

# Return the element at r, c 
proc `[]`(mat: Matrix, r, c: int): Matrix.T = 
    result = mat[mat.index(r, c)] 

# Set the element at r, c 
proc `[]=`(mat: var Matrix, r, c: int, val: Matrix.T) = 
    mat[mat.index(r, c)] = val 

# Add a value to every element in the matrix 
proc `+=`(mat: var Matrix, val: Matrix.T) = 
    for i in 0 .. mat.high: 
    mat[i] += val   

# Add a value to element at r, c 
proc `[]+=`(mat: var Matrix, r, c: int, val: Matrix.T) = 
    mat[mat.index(r, c)] += val 


# A test case 
var mat: Matrix[float, 3, 4] # matrix with 3 rows and 4 columns 
mat[1, 3] = 7.0 
mat += 1.0 

# add 8.0 to entry 1, 3 in matrix 
`[]+=`(mat, 1, 3, 8.0) # works fine 

所有这一切工作正常,但我希望能够与东西来取代最后一行像

mat[1, 3] += 4.0 

这是不行的(没想到它要么)。如果我尝试它,我得到

Error: for a 'var' type a variable needs to be passed 

如何创建具有此行为的附加赋值运算符?我猜测我需要一个除proc以外的其他东西来完成这个任务。

+0

有趣的是,我昨天完全一样,并且有同样的问题。将标题改为_Nim运算符重载:如何结合'[]'和'+ ='?_或类似的东西来使实际主题更清晰? – bluenote10 2015-04-07 10:55:35

回答

5

有两种方法可以做到这一点:为var Matrix

  • 超载[]并返回var T(这需要稔当前devel的分支):

    proc `[]`(mat: Matrix, r, c: int): Matrix.T = 
        result = mat[mat.index(r, c)] 
    
    proc `[]`(mat: var Matrix, r, c: int): var Matrix.T = 
        result = mat[mat.index(r, c)] 
    
  • []一模板改为:

    template `[]`(mat: Matrix, r, c: int): expr = 
        mat[mat.index(r, c)] 
    

    这会导致一个问题,当mat不是价值,而是更复杂的东西:

    proc x: Matrix[float, 2, 2] = 
        echo "x()" 
    
    var y = x()[1, 0] 
    

    这将打印x()两次。

+0

第二种方法。很好地工作。谢谢。 – COM 2015-04-05 20:44:56

+0

也尝试了第一种方法。发出错误“错误:不明确的调用”。我假设这是因为我没有使用最新的devel分支(使用稳定版本0.10.2)。只是想确保它不是其他问题。 – COM 2015-04-07 17:10:49