2011-12-24 169 views
22

我學習d,並看到了很多這樣的代碼:感嘆號操作符?

ushort x = to!ushort(args[1]); 

我認爲這蒙上args[1]ushort,但是這是什麼和cast(ushort)之間的區別?

編輯:感嘆號運算符有什麼其他用途?

回答

31

在d,

to!ushort(args[1]) 

是用於模板實例

to!(ushort)(args[1]) 

速記和是如C++ /爪哇/ C#語言類似於

to<ushort>(args[1]) 

感嘆號是要注意的事實,它不是一個常規的參數,而是一個模板參數。

的符號確實使用角括號,因爲這些都是可笑很難正確地解析爲一個編譯器(他們所做的語法很上下文敏感的),這使得它更加困難,以實現正確的編譯器。有關更多信息,請參閱here

我所知道的唯一的其他用途就是一元'不'操作(例如false == !true)......我現在想不出任何其他用途。


關於演員:

cast(ushort)選中投,所以如果該值超出範圍也不會拋出異常。

to!ushort()檢查強制轉換,因此如果該值超出範圍,則會引發異常。

+0

非常感謝=]很棒的回答! – thwd 2011-12-24 10:07:11

+3

看來也是這樣!更多的是一個詞法轉換,例如!string(f)對於浮點f和cast(string)是有效的f - 不是。 – 2011-12-24 10:10:38

+5

我會指出,從技術上講,「to!ushort(val)」實際上並不是演員。這是一個使用函數'std.conv.to'的轉換。它被檢查,但如果你開始把它稱爲演員,你可能會導致混淆。鑄造只能由鑄造操作員完成。 – 2011-12-24 19:35:47

3

此處的感嘆號不是運算符,它只是顯式模板實例化語法的一個令牌部分(詳細描述在here中)。

std.conv.todocs)是用於在任意類型之間轉換的函數模板。它完全在圖書館內實施,並沒有特別的語言支持。與演員經營者相比,它有更廣泛和不同的範圍。

to模板需要兩個類型參數;一個「to」類型和一個「from」類型。在你的例子中,模板被顯式實例化,其中「to」參數的參數爲​​ushort,第二個參數string(假設args來自main的第一個參數)自動從傳遞給功能(args[1])作爲「from」參數。

生成的函數接受一個字符串參數,並返回從該字符串解析的ushort,如果失敗則返回異常。演員操作員不會嘗試這種高級轉換。

注意,如果有多於一個明確的模板參數,或參數中有一個以上的令牌(ushort是一個關鍵字標記),必須用括號中的模板參數列表:

ushort result; 
result = to!(typeof(result))(args[1]); 

在這個例子中,typeof,(,result)是四個獨立的標記,因此需要括號。

要回答你的最後一個問題,在!令牌也可用於一元不操作,無關模板實例:

bool yes = true; 
bool no = !yes; // 'no' is false 
2

您已經jA_cOp和Merhdad有兩個優秀的答案。我只想直接回答OP的問題(這個和cast(ushort)有什麼區別?) - 區別在於cast(ushort)args[1]不行(你不能像字符串一樣轉換成uint),而to!(type)(param)模板知道如何處理字符串以及如何將其轉換爲基元類型。

+0

非常感謝,這是有道理的。 – thwd 2011-12-24 23:16:14