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

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都是平等的,但如果length0两个阵列,它并不关心什么的价值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语句或循环的条件下单独放置一个数组.