2016-02-27 41 views
2

好像有沒有簡單的方法來防止D的import語句從混濁的全局命名空間:只要你import std.stdio我可以避免使用D導入來污染公共名稱空間嗎?

module x;  
import std.stdio; 

void main() { 
    writeln("Hello!"); 
} 

writeln現在是全球性的。來自[language with namespaces],這將是很好,如果我只能參考std.stdio.writeln,特別是在一兩週內,我可以很容易地告訴什麼提供writeln

閱讀Namespaces with classes and structs?後,在我看來,這應該做想我(作爲笨拙,因爲它是):

module x; 
import std.stdio; 

class String { 
    struct write { 
    auto println = writeln; 
    } 
} 

void main() { 
    String string = new String(); 
    string.write.println("Hello!"); 
} 

,但我得到Error: variable [...] type void is inferred from initialiser [...], and variables cannot be of type void,這意味着功能走樣了。如果我寫C,我可以理解命名空間的缺乏(但我仍然可以用結構和點符號來實現它們)。有沒有辦法讓導入的名稱不是如此全球?

回答

7

我傾向於同意@weltensturm - D優雅地處理衝突,並且人爲地創建名稱空間只會使事物混淆。

D(恕我直言)的一個不錯的部分是避免在其他 語言中看到的那些長名稱,而不必擔心會發生可怕的事情。

但是,如果你真的需要,看看在文檔上 modules,這顯示如何命名模塊:

import io = std.stdio; 

void main() 
{ 
    io.writeln("hello!");  // ok, calls std.stdio.writeln 
    std.stdio.writeln("hello!"); // error, std is undefined 
    writeln("hello!");   // error, writeln is undefined 
} 

您也可以使用靜態導入,所以你不得不使用完全合格的名稱:

static import std.stdio; 

void main() 
{ 
    std.stdio.writeln("hello!"); // OK 
    writeln("hello!");   // error, writeln is undefined 
} 
+2

只記得'靜態導入'是一件事情。這可能是你正在尋找的東西。 – rcorre

+0

你的意思是 - 你剛剛閱讀我的評論。 ;) – DejanLekic

+0

哎呀,沒有意識到你在我編輯的時候回答了。你的答案可能更好,因爲它削減了追逐的權利:) – rcorre

4

您是否在尋找選擇性進口(可在http://dlang.org/spec/module.html找到)?

import std.stdio : writeln; 
+0

這很有趣,但'writeln'仍然是全局聲明,並不強迫我使用'std.stdio.writeln' – cat

+0

這是什麼目的,反正呢?看來我仍然可以在'std.stdio.write'處理,即使我只輸入了std.stdio:writeln;' – cat

+1

@cat這是一個當選擇性地導入writeln時可以訪問std.stdio.write的bug。 AFAIK,選擇性進口從未正常工作(https://issues.dlang.org/show_bug.cgi?id=314)。但是,它在發佈時應該在2.071中修復,因爲已經有許多與導入相關的修補程序已經成爲主程序,特別是針對該錯誤。 –

4

你的例子的問題是你正在調用writeln,而不是它的指針。嘗試&writeln。您還應該聲明它爲static,因此您不必實例化名稱空間。 (D中只有靜態函數的類與命名空間非常相似)。但是你應該避免人爲地創建名稱空間,因爲D處理衝突的效果非常好,並且只會增加所需的輸入。

至於D的導入系統:導入模塊中的每個名稱都在當前的模塊中可用。但是,只要您導入名稱衝突的模塊,您將不得不使用全名。

+0

「*致電writeln *」我不需要括號來做到這一點? – cat

+0

'別名'的工作方式,我期待無差別。 – cat

+2

@cat [括號是可選的](http://dlang.org/spec/function.html#optional-parenthesis) – sigod

5

這是相當簡單 - 如果你不喜歡的命名空間污染,那麼你必須做靜態導入

這裏是d規範說什麼(http://dlang.org/spec/module.html,部分「靜態導入」):

基本進口相對較少的模塊和進口程序工作。如果有大量導入,名稱衝突可能會在各種導入模塊中的名稱之間開始發生。阻止這種情況的一種方法是使用靜態導入。靜態導入需要一個使用完全合格的名稱來引用模塊的名稱:

例子:

static import std.stdio; 

void main() { 
    writeln("hello!");   // error, writeln is undefined 
    std.stdio.writeln("hello!"); // ok, writeln is fully qualified 
} 

如果我的代碼從一個模塊只需要一個或兩個符號,我用的是選擇進口正如Max Alibaev所述。假設我將使用writeln()很多。 - 那麼我很可能在我的D代碼中有一行import std.stdio : writeln;

相關問題