在 nim 中過程或方法有兩種引數型別,一種是前面有 var 關鍵字 的引數,另一種是不帶 var 的引數。
例如:
proc divmod(a, b: int; res, remainder: var int) =
res = a div b
remainder = a mod b
var x, y: int
divmod(8, 5, x, y) # modifies x and y
assert x == 1
assert y == 3
在上面的例子中,a,b是不帶 var 的引數,它們在過程中是不允許改變的,而 res, remainder 在過程中是能夠改變其值的。 傳遞給 var 引數的必須是乙個 l-value.
l-value 介紹:
乙個表示式能指定乙個產生乙個值或位置的計算。產生位置的表示式就是 l-values
。(比如:
var x = 5
中的 x
就是乙個
l-value
。 5
就不是)。乙個 l-value
能夠表示乙個位置或者這個位置包含的值,這取決於語境。表示式的值能夠被靜態確定的被稱為常量表示式。它們不是 l-values
。let 宣告的變數不是
l-values。
var 引數是作為隱式的指標實現的,上面的例子與這個例子是等價的:
proc divmod(a, b: int; res, remainder: ptr int) =
res = a div b
remainder = a mod b
var x, y: int
divmod(8, 5, addr(x), addr(y))
assert x == 1
assert y == 3
nim 中的引數傳遞傳的是位址,var 引數型別允許過程改變其值,是通過隱式的指標實現的,指標指向了變數的位址,所以改變的是原來變數的內容。不是var 引數的不允許改變其值。
變數在記憶體中的儲存:
上面的例子可以通過返回乙個元組的方式來實現:
proc divmod(a, b: int): tuple[res, remainder: int] =
(a div b, a mod b)
var t = divmod(8, 5)
assert t.res == 1
assert t.remainder == 3
var (x, y) = divmod(8, 5) # tuple unpacking
assert x == 1
assert y == 3
乙個過程、轉換器或者迭代器可能返回乙個 var
型別,這意味著 這個返回值是乙個
l-value
和能夠被呼叫者改變:
var g = 0
proc writeaccesstog(): var int =
result = g
writeaccesstog() = 6
assert g == 6
要注意賦給 result 的值得是乙個 l-value .
import strutils
discard """
proc writeaccesstog(): var int =
var g = 0
result = g # error! error: address of 'g' may not escape its stack frame
"""
discard """
proc writeaccesstog(g:int): var int =
result = g # error! error: expression has no address
"""proc writeaccesstog(g:var int): var int =
result = g
proc writeaccesstog2(g:ptr int): var int =
result = g
proc writeaccesstog3(g:ptr string): var string = #帶var 和不帶是不一樣的。 帶var 是隱式的指標操作, result 與 g 指向同一位置。
echo "repr g = ",repr(g) #不帶 var, result 在棧中重新分配乙個空間。
#echo "repr result = ",repr(result)
result = g
echo "repr result = ",repr(result)
g[0] = 'a'
var
var1 = 5
var2 = "yrs"
echo writeaccesstog(var1)
echo writeaccesstog2(addr(var1))
echo "addr(var2) = ",biggestint(cast[int](addr(var2))).tohex(12)
echo "repr var2 = ",repr(var2)
echo "returned = ", repr(writeaccesstog3(addr(var2)))
echo "repr var2 = ",repr(var2)
對於迭代器,乙個元組的一部分返回型別可以有乙個var
型別:
iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] =
for i in 0..a.high:
yield (i, a[i])
var x:seq[string]
x = @["a","b","c"]
for m in mpairs(x):
echo m
在標準庫里每乙個返回乙個 var
型別的程式的名子都是以
m 作為字首。
WebApi中的引數傳遞
webapi引數傳遞總結 在webapi中,請求主體 httpcontent 只能被讀取一次,不被快取,只能向前讀取的流。舉例子說明 服務端方法 void action int id,string name 所有引數都是簡單型別,因而都將來自url 服務端方法 void action fromuri...
C 中的引數傳遞
c 中的引數傳遞,根據引數的型別可以分為四類 在預設情況下,clr方法中引數的傳遞都是按值傳遞 對於引數又分為 形參 被呼叫方法中的引數,實參 呼叫方法的引數 class program addnum就是形參,也就是被呼叫方法中的引數 private static void add int addn...
python中的引數傳遞
我們知道c語言中只有值傳遞 位址也是值 c 中額外有引用傳遞,那麼在python中的引數是如何傳遞的呢,要理解這一點,我們就需要知道python傳遞的到底是什麼,在c c 中有變數的概念,但是在python中是沒有這個概念的,在python的世界中,萬物皆物件,我們可以通過名字來操控這些物件,先來解...