2014-07-09 30 views
4

我知道out的工作原理與ref非常相似,不同之處在於它在進入函數時將傳遞的參數初始化爲默認值。什麼是D「out」存儲類有用?

我的問題是在什麼情況下這將是有用的「在函數輸入時重置變量」?

這將是偉大的如果有人能告訴我一個例子out會比ref更有用。

回答

7

refout之間的主要區別是意圖。當使用ref時,預計傳入的值將被函數使用。該功能可能會或可能不會設置它。如果你願意,你甚至可以有const ref,這意味着傳入的變量不會被複制,但它也不能被改變。另一方面,

const out沒有任何意義,因爲out的意圖是變量將在函數中設置。使用out本質上是一種向函數添加另一個返回值的方法。 ref可以使用,但使用ref不會向調用方指示傳入的值將不會被使用,或者甚至不一定指定該變量將被分配給該值,而out表示該值將不會被用於被使用,並且變量將被分配給

out將變量設置爲其默認值的原因是爲了避免錯誤。如果函數的目的是使用out參數作爲另一個返回值,那麼您通常不希望該函數受傳入值影響。通過將參數out設置爲其默認值,它可以保證變量總是與該函數相同的值,而不管傳入的是什麼,所以避免了由於函數意外地依賴於該值而導致的錯誤。

現在,沒有那一個out參數的函數內分配的要求,但它確實傳達給呼叫者是這樣的意圖,它不管給它分配的默認值,所以從調用方的角度,out參數總是被分配一個值(即使它是默認值)。因此,如果有意義的話,該函數可以自由設置out參數(例如,如果默認值是在某些情況下應該「返回」的)。

2

那麼「out」表示你必須在函數退出前分配變量。用「ref」,不一定。如果我的記憶沒有欺騙我,我認爲就是這樣。另一方面,參考C++中的參考,您可以選擇修改該值,也可以保持原樣。

因此,比如說,如果您將某種對象傳遞給尚未初始化的函數,則可以將它傳遞給「out」並讓函數接受「out」,並且在可以創建的函數中那個對象。但是,如果函數接受「ref」並傳遞一個未初始化的對象,我認爲編譯器會給你一個錯誤。

Charles Petzold的.Net Zero書(可免費下載)詳細解釋了所有這些美味佳餚。我建議你閱讀它。

+0

但是D總是使用默認值初始化數據類型,沒有像C&C++ – Algo

+0

那樣的「未初始化的對象」,好吧,你是對的。最近我一直在編寫太多的C++代碼。:) – armanali

+0

這裏總是有點強大。未初始化的對象可能在D中(不在@safe D中),並帶有void聲明。 int i = void;你基本上聲明一個變量的C方式。 –

4

out類似於ref,但它與來電者通信說您只有打算爲該函數內的變量賦值。這只是慣例,但編譯器通過初始化函數輸入的變量init來強制執行它,所以除非打算賦值,否則將變量標記爲out確實沒有意義。

的編譯器強制執行,你必須做出的功能,如在轉讓給了參數,下面是完全合法的:

void test(out int n) 
{ 
    //Do nothing 
} 

void main() 
{ 
    int x; 
    test(x); 
} 

如果你有C遺傳背景,這是多還是不像通用的C模式,其中函數需要一個指向變量的指針,以便在函數內初始化它。