Nim 中的引數傳遞

2021-07-05 09:53:34 字數 3255 閱讀 4078

在 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的世界中,萬物皆物件,我們可以通過名字來操控這些物件,先來解...