2015-04-05 90 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