为什么
if (x) {
f();
}
如果f()
是空字符串x
,请致电""
不应该在D中空出字符串隐式转换为bool
false
,就像在Python中一样,当空数组执行时(在D中)?
更新:我修正了问题。我错误地颠倒了推理逻辑。幸运的是,聪明的D头脑无论如何理解我的意思;)
答案 0 :(得分:10)
条件和if
语句和循环由编译器强制转换为bool
。所以,
if(x) {...}
变为
if(cast(bool)x) {...}
对于数组,转换为bool
等同于测试其ptr
属性是否不是null
。所以,它变成
if(x.ptr !is null) {...}
对于数组,这实际上是一个非常糟糕的测试,因为null
数组被认为与空数组相同。因此,在大多数情况下,您不关心数组是否为null
。数组本质上是一个看起来像
struct Array(T)
{
T* ptr;
size_t length;
}
==
运算符将检查ptr
引用的所有元素是否相等,但如果两个数组的length
为0
,则无关紧ptr
的价值是什么。这意味着""
和null
相等([]
和null
也是如此。但是,is
运算符会明确检查ptr
属性是否相等,因此根据""
运算符,null
和is
将不相同,并且空的特定数组是否具有null
ptr
取决于其值的设置方式。所以,数组是空的这个事实真的没有说明它是null
还是is
。您必须与if(x) {...}
运营商核实才能确定。
所有这一切的结果是,将数组(或字符串)直接放在像你一样的条件下通常是不好的做法
if(x.empty) {...}
相反,你应该清楚你正在检查什么。你关心它是否是空的?在这种情况下,您应该检查
if(x.length == 0} {...}
或
null
或者你真的关心它是is
吗?在这种情况下,请使用if(x is null) {...}
运算符:
null
条件中数组的行为与语言的其余部分一致(例如,检查指针和引用类型以查看它们是否为if
),但不幸的是,在实践中,数组的这种行为很容易出错。所以,我建议你不要在{{1}}语句或循环的条件下单独放置一个数组。
答案 1 :(得分:4)
数组的默认转换查看.ptr
,这意味着只有默认的初始化数组(或显式设置为null)才会计算为false
作为附加效果D中的字符串文字被\0
终止,这意味着("")[0] == '\0'
因此("").ptr
不能为空(这将导致段错误)
IMO它应该查看长度,你可以在需要时使用ptr
答案 2 :(得分:3)
我尝试时会这样做......
void main() {
import std.stdio;
string s = "";
if(s)
writeln("true"); // triggered
}
如果是“string s = null;” (这是默认的初始化),它没有,因为null转换为false,但“”在我的计算机上是可以的。你确定它不是空的吗?
顺便说一句,如果你想测试(非)空虚,我喜欢这样做的方式是if(x.length)和if(x.length == 0)。那些对于“”和null都一致地工作,那么如果你特别想要null,请执行if(x为null)。它只是更清楚一点,特别是因为“”和“null”在D中的许多其他语境中是可以互换的。