[英]How should I use storage class specifiers like ref, in, out, etc. in function arguments in D?
D中的函數參數有相對多的存儲類說明符,它們是:
in
(相當於const scope
) out
ref
scope
lazy
const
immutable
shared
inout
他們背后的理性是什么? 他們的名字已經提出了明顯的用途。 但是,有一些懸而未決的問題:
ref
結合in
for struct
type函數參數嗎? out
暗示ref
隱含? ref
是否有意義? (默認情況下,類類型是引用。) ref
? const
作為內置算術類型嗎? 更一般地說:在內置類型,數組,結構,類和接口的情況下,何時以及為什么我應該使用哪個存儲類說明符用於函數參數類型? (為了稍微區分問題的范圍,請不要討論shared
,因為它有其獨立的含義。)
我不會默認使用。 ref
參數只接受左值,這意味着你將改變傳入的參數。如果你想避免復制,那么使用const ref
或auto ref
。 但是const ref
仍然需要一個左值,所以除非你想復制你的函數,否則它通常比它的價值更令人討厭。 而auto ref
將避免復制左值(它基本上使得它有一個函數的版本,它接受ref
的lvalues和一個不帶ref
rvalues),它只適用於模板,限制了它的用處。 使用const
會產生深遠的影響,因為D的const
是可傳遞的,並且事實上它是從變量中拋棄const
並修改它的未定義行為。 因此,雖然它通常很有用,但默認使用它可能會讓你陷入困境。
使用in
為const
提供scope
,我通常建議不要使用const
。 函數參數的scope
應該使它不會引用該數據,但是對它的檢查還沒有正確實現,所以你實際上可以在很多情況下使用它而不是合法的。 在某些情況下, scope
是非常寶貴的(例如,使用委托,因為它使得編譯器不必為它分配閉包),但對於其他類型,它可能很煩人(例如,如果傳遞數組是scope
,然后您無法從該函數返回切片到該數組)。 任何包含任何數組或引用類型的結構都會受到影響。 雖然你現在不會有很多關於錯誤使用scope
抱怨,如果你一直在使用它,你一定會在修復后遇到很多錯誤。 此外,它對於值類型完全沒有意義,因為它們沒有提到逃避。 因此, in
值類型(包括值類型的結構)上使用const
和in
實際上是相同的。
out
與ref
相同,只是它將參數重置為其init
值,這樣無論傳入的變量的先前狀態如何,您始終都會獲得相同的值。
幾乎總是就函數參數而言。 當你有特定的需要時,你使用const
或scope
或whatnot,但我不建議默認使用它們中的任何一個。
當然可以。 ref
與類引用的概念是分開的。 它是對傳入的變量的引用。如果我這樣做的話
void func(ref MyClass obj) { obj = new MyClass(7); } auto var = new MyClass(5); func(var);
然后var將在調用func
而不是new MyClass(5)
之后引用新構造的new MyClass(7)
new MyClass(5)
。 你通過ref
傳遞引用。 這就像獲取引用的地址(如var
)為您提供指向引用的指針而不是指向類對象的指針。
MyClass* p = &var; //points to var, _not_ to the object that var refers to.
和班級一樣的交易。 ref
使參數引用傳入的變量。例如
void func(ref int[] arr) { arr ~= 5; } auto var = [1, 2, 3]; func(var); assert(var == [1, 2, 3, 5]);
如果func
沒有通過ref
接受它的參數,則var
將被切片,並且附加到arr
將不會影響var
。 但由於參數是ref
,所以對arr
做的任何事都是對var
。
這完全取決於你。 使它成為const
使得你不能改變它,這意味着如果你不打算改變它,你就會受到保護而不會意外地改變它。 它也可以啟用一些優化,但是如果你從不寫入變量,並且它是內置的算術類型,那么編譯器就知道它永遠不會改變,優化器應該能夠進行那些優化(不管它是否確實如此)不取決於編譯器的實現)。
對於幾乎所有情況下的內置算術類型, immutable
和const
實際上是相同的,所以我個人認為,如果我想保證這樣的變量不會改變,我只使用immutable
變。 通常,如果可以使用immutable
而不是const
則可以為您提供更好的優化和更好的保證,因為它允許跨線程隱式共享變量(如果適用),並且它始終保證變量不能被變異(而對於參考) types, const
只表示該引用不能改變對象,而不是它不能被改變)。
當然,如果你盡可能地標記你的變量const
和immutable
,那么它確實至少在某些時候幫助編譯器進行優化,並且它可以更容易地捕獲你不想改變的東西。 它還可以使您的代碼更容易理解,因為您知道變量不會被變異。 因此,大量使用它們可能很有價值。 但同樣,使用const
或immutable
可能過於嚴格,具體取決於類型(雖然這不是內置整數類型的問題),因此只需將所有內容自動標記為const
或immutable
就會導致問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.