为什么
if (x) {
f();
}
f()
如果x
是空字符串则调用""
?
bool
false
D中的空字符串不应该像在Python中那样隐式转换为空数组时(在D中)吗?
更新:我解决了这个问题。我错误地颠倒了推理逻辑。幸运的是,聪明的 D 头脑无论如何都明白我的意思;)
为什么
if (x) {
f();
}
f()
如果x
是空字符串则调用""
?
bool
false
D中的空字符串不应该像在Python中那样隐式转换为空数组时(在D中)吗?
更新:我解决了这个问题。我错误地颠倒了推理逻辑。幸运的是,聪明的 D 头脑无论如何都明白我的意思;)
条件、if
语句和循环bool
由编译器强制转换。所以,
if(x) {...}
变成
if(cast(bool)x) {...}
在数组的情况下,强制转换bool
为等同于测试其ptr
属性是否为 not null
。所以,它变成
if(x.ptr !is null) {...}
在数组的情况下,这实际上是一个非常糟糕的测试,因为null
数组被认为与空数组相同。因此,在大多数情况下,您并不关心数组是否null
存在。数组本质上是一个结构,看起来像
struct Array(T)
{
T* ptr;
size_t length;
}
The ==
operator will check whether all of the elements referred to by ptr
are equal, but if length
is 0
for both arrays, it doesn't care what the value of ptr
is. That means that ""
and null
are equal (as are []
and null
). However, the is
operator explicitly checks the ptr
properties for equality, so ""
and null
won't be the same according to the is
operator, and whether a particular array which is empty has a null
ptr
depends on how its value was set. So, the fact that an array is empty really says nothing about whether it's null
or not. You have to check with the is
operator to know for sure.
The result of all this is that it's generally bad practice to put an array (or string) directly in a condition like you're doing with
if(x) {...}
Rather, you should be clear about what you're checking. Do you care whether it's empty? In that case, you should check either
if(x.empty) {...}
or
if(x.length == 0} {...}
Or do you really care that it's null
? In that case, use the is
operator:
if(x is null) {...}
The behavior of arrays in conditions is consistent with the rest of the language (e.g. pointer and reference types are checked to see whether they're null
or not), but unfortunately, in practice, such behavior for arrays is quite bug-prone. So, I'd advise that you just don't ever put an array by itself in the condition of an if
statement or loop.
数组的默认转换查看.ptr
,这意味着只有默认的初始化数组(或显式设置为 null)评估为 false
作为附加效果 D 中的字符串文字被\0
终止,这意味着("")[0] == '\0'
不能("").ptr
为空(这将导致段错误)
IMO 它应该查看长度,您可以在需要时使用 ptr
当我尝试它时,它会...
void main() {
import std.stdio;
string s = "";
if(s)
writeln("true"); // triggered
}
如果是“字符串 s = null;” (这是默认初始化),它没有,因为 null 转换为 false,但是 "" 在我的计算机上是可以的。你确定它不为空吗?
顺便说一句,如果你想测试(非)空性,我更喜欢这样做的方式是 if(x.length) 和 if(x.length == 0)。这些对“”和 null 都有效,然后如果您特别想要 null,请执行 if(x is null)。它只是更清楚一点,特别是因为 "" 和 null 在 D 中的许多其他上下文中是可以互换的。