不应该将空字符串隐式转换为false

时间:2013-09-01 22:07:01

标签: string d implicit-conversion boolean-logic

为什么

if (x) {
    f();
}
如果f()是空字符串x,请致电""

不应该在D中空出字符串隐式转换为bool false,就像在Python中一样,当空数组执行时(在D中)?

更新:我修正了问题。我错误地颠倒了推理逻辑。幸运的是,聪明的D头脑无论如何理解我的意思;)

3 个答案:

答案 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引用的所有元素是否相等,但如果两个数组的length0,则无关紧ptr的价值是什么。这意味着""null相等([]null也是如此。但是,is运算符会明确检查ptr属性是否相等,因此根据""运算符,nullis将不相同,并且空的特定数组是否具有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中的许多其他语境中是可以互换的。