簡體   English   中英

我應該如何在D中的函數參數中使用存儲類說明符,如ref,in,out等?

[英]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

他們背后的理性是什么? 他們的名字已經提出了明顯的用途。 但是,有一些懸而未決的問題:

  1. 默認情況下,我應該使用ref結合in for struct type函數參數嗎?
  2. 難道out暗示ref隱含?
  3. 什么時候應該使用沒有
  4. 類和/或接口上的ref是否有意義? (默認情況下,類類型是引用。)
  5. 如何對陣列切片進行ref
  6. 我應該盡可能使用const作為內置算術類型嗎?

更一般地說:在內置類型,數組,結構,類和接口的情況下,何時以及為什么我應該使用哪個存儲類說明符用於函數參數類型? (為了稍微區分問題的范圍,請不要討論shared ,因為它有其獨立的含義。)

  1. 我不會默認使用。 ref參數只接受左值,這意味着你將改變傳入的參數。如果你想避免復制,那么使用const refauto ref 但是const ref 仍然需要一個左值,所以除非你想復制你的函數,否則它通常比它的價值更令人討厭。 auto ref將避免復制左值(它基本上使得它有一個函數的版本,它接受ref的lvalues和一個不帶ref rvalues),它只適用於模板,限制了它的用處。 使用const會產生深遠的影響,因為D的const是可傳遞的,並且事實上它是從變量中拋棄const並修改它的未定義行為。 因此,雖然它通常很有用,但默認使用它可能會讓你陷入困境。

    使用inconst提供scope ,我通常建議不要使用const 函數參數的scope應該使它不會引用該數據,但是對它的檢查還沒有正確實現,所以你實際上可以在很多情況下使用它而不是合法的。 在某些情況下, scope是非常寶貴的(例如,使用委托,因為它使得編譯器不必為它分配閉包),但對於其他類型,它可能很煩人(例如,如果傳遞數組是scope ,然后您無法從該函數返回切片到該數組)。 任何包含任何數組或引用類型的結構都會受到影響。 雖然你現在不會有很多關於錯誤使用scope抱怨,如果你一直在使用它,你一定會在修復后遇到很多錯誤。 此外,它對於值類型完全沒有意義,因為它們沒有提到逃避。 因此, in值類型(包括值類型的結構)上使用constin實際上是相同的。

  2. outref相同,只是它將參數重置為其init值,這樣無論傳入的變量的先前狀態如何,您始終都會獲得相同的值。

  3. 幾乎總是就函數參數而言。 當你有特定的需要時,你使用constscope或whatnot,但我不建議默認使用它們中的任何一個。

  4. 當然可以。 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. 
  5. 和班級一樣的交易。 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

  6. 這完全取決於你。 使它成為const使得你不能改變它,這意味着如果你不打算改變它,你就會受到保護而不會意外地改變它。 可以啟用一些優化,但是如果你從不寫入變量,並且它是內置的算術類型,那么編譯器就知道它永遠不會改變,優化器應該能夠進行那些優化(不管它是否確實如此)不取決於編譯器的實現)。

    對於幾乎所有情況下的內置算術類型, immutableconst實際上是相同的,所以我個人認為,如果我想保證這樣的變量不會改變,我只使用immutable變。 通常,如果可以使用immutable而不是const則可以為您提供更好的優化和更好的保證,因為它允許跨線程隱式共享變量(如果適用),並且它始終保證變量不能被變異(而對於參考) types, const只表示該引用不能改變對象,而不是它不能被改變)。

    當然,如果你盡可能地標記你的變量constimmutable ,那么它確實至少在某些時候幫助編譯器進行優化,並且它可以更容易地捕獲你不想改變的東西。 它還可以使您的代碼更容易理解,因為您知道變量不會被變異。 因此,大量使用它們可能很有價值。 但同樣,使用constimmutable可能過於嚴格,具體取決於類型(雖然這不是內置整數類型的問題),因此只需將所有內容自動標記為constimmutable就會導致問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM