2011-12-24 173 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