Nor*_*löw 3 string boolean-logic d implicit-conversion
为什么
if (x) {
f();
}
Run Code Online (Sandbox Code Playgroud)
f()
如果x
是一个空字符串调用""
?
不应该将D中的空字符串隐式转换为bool
false
类似于Python中的字符串,并且当空数组执行时(在D中)?
更新:我修正了问题.我错误地颠倒了推理逻辑.幸运的是,聪明的D头脑无论如何理解我的意思;)
Jon*_*vis 10
条件和if
语句以及循环bool
由编译器强制转换.所以,
if(x) {...}
Run Code Online (Sandbox Code Playgroud)
变
if(cast(bool)x) {...}
Run Code Online (Sandbox Code Playgroud)
在数组的情况下,cast to bool
相当于测试它的ptr
属性是否不是null
.所以,它变成了
if(x.ptr !is null) {...}
Run Code Online (Sandbox Code Playgroud)
对于数组,这实际上是一个非常糟糕的测试,因为null
数组被认为与空数组相同.因此,在大多数情况下,您不关心数组是否null
存在.数组本质上是一个看起来像的结构
struct Array(T)
{
T* ptr;
size_t length;
}
Run Code Online (Sandbox Code Playgroud)
该==
运营商将检查是否所有提到了元素ptr
都是平等的,但如果length
是0
两个阵列,它并不关心什么的价值ptr
是.这意味着""
并且null
是相同的(原样[]
和null
).然而,is
操作者明确地检查ptr
是否相等的特性,所以""
并null
不会根据相同的is
操作,和一个特定的阵列,其是空的是否具有null
ptr
取决于它的值是如何被设置.所以,数组是空的这个事实真的没有说明它是否null
存在.您必须与is
操作员核实才能确定.
所有这一切的结果是,将数组(或字符串)直接放在像你一样的条件下通常是不好的做法.
if(x) {...}
Run Code Online (Sandbox Code Playgroud)
相反,你应该清楚你正在检查什么.你关心它是否是空的?在这种情况下,你应该检查
if(x.empty) {...}
Run Code Online (Sandbox Code Playgroud)
要么
if(x.length == 0} {...}
Run Code Online (Sandbox Code Playgroud)
或者你真的关心它null
吗?在这种情况下,使用is
运算符:
if(x is null) {...}
Run Code Online (Sandbox Code Playgroud)
条件中数组的行为与语言的其余部分一致(例如,检查指针和引用类型以查看它们是否null
存在),但不幸的是,在实践中,这种数组行为很容易出错.所以,我建议你不要在if
语句或循环的条件下单独放置一个数组.