2015-12-18 14 views
3

Dlang描述out參數爲:是一個out參數,它的值被隱式重新初始化了嗎?

在與用於 其類型的默認值的函數入口進行初始化的參數。

參數初始化爲函數入口的默認值後,是不是本質上只是一個ref

import std.stdio; 

void foo(out int x) 
{ 
    writeln(x); //prints 0 
    x = 2; 
} 

void main() 
{ 
    int x = 1; 
    writeln(x); //prints 1 
    foo(x); 
    writeln(x); //prints 2 
} 

我沒有看到比較outref任何文件。
它是精確的概念化的out參數從寫作的捷徑:

import std.stdio; 

void foo(ref int x) 
{ 
    x = x.init; //happens implicitly 
    writeln(x); //prints 0 
    x = 2; 
} 

void main() 
{ 
    int x = 1; 
    writeln(x); //prints 1 
    foo(x); 
    writeln(x); //prints 2 
} 

我不知道該語言的複雜性,所以我很擔心,有這種印象將導致未來我悲傷無法預料情況。

這些parameter storage classes之間可以有更強烈的區別,還是它真的是自動重新初始化的ref參數?

回答

2

是的,這就是今天的實現,但這不完全是它的語義意義。

認爲out params作爲額外的返回值,而不是傳統意義上的參數,你應該沒問題。函數不能取其返回值的地址,也不能通過它接收數據。 out參數也不應該以這些方式使用。


D從來沒有用過ref。它使用in,outinout作爲參數存儲類。

in意味着(和手段,它仍然存在),你會看,但不能修改或保存一個對它的引用(後者是什麼使得它從const不同 - 你被允許存儲const,但不是inscope params,它可以讓編譯器理論上優化它們的內存分配)。它僅用於數據消費。

out表示該函數將存儲該變量中的數據,但不會查看或存儲該變量。當函數將結果寫入其中時,預先已經存在的值將會丟失。編譯器在函數輸入時重置它,以保證程序不依賴於通過它傳入的某個值。

最後,舊的inout是它將數據,並存儲一個值。今天(好吧,從五年前開始),這種用法早已消失,而inout意味着完全不同的東西(const,但返回的constness以輸入爲條件; const/immutable/mutable限定符與它們的作用相同)和舊的用法被替換爲ref,這也擴大了含義:它不再是數據進出,而是對另一個變量的全面引用,這意味着您可以像接收地址那樣執行操作。

雖然out實現爲ref加上自動重新初始化,但您應該記住原來的含義:您將數據寫入它,但不要做任何其他操作。不要拿它的地址 - 這是合法的ref(除非它是scope refin ref ...)但不正確out。你應該寫信給它,沒有更多。

+0

「把params看作是額外的返回值」:這是正確的,但我會說out參數不會用在慣用的D2代碼中。使用Tuple!()作爲返回值通常是更好的解決方案。 – jpf

+0

我不喜歡Tuple(如果我走這條路線,我更喜歡返回一個帶命名字段的命名結構體),但是,你說得對,很多代碼都是這樣做的,並且輸出參數相對較少。 –

2

是一個out參數是一個ref,其值被隱式重新初始化?

是的。

參數在函數入口上用默認值初始化後,是不是它本質上只是一個ref?

是的。

這些參數存儲類之間可以有更強烈的區別,還是它真的是自動重新初始化的參數參數?

後者。至少,這就是我的想法。我希望我不會錯過任何東西。

+0

這是真的,但我認爲這個故事更多。讓我發表我的寫作作爲答案。 –

相關問題