【问题标题】:Shouldn't Empty Strings Implicitly Convert to false不应将空字符串隐式转换为 false
【发布时间】:2013-09-01 22:07:01
【问题描述】:

为什么

if (x) {
    f();
}

如果x 是空字符串"",则调用f()

D 中的空字符串不应该像在 Python 中那样隐式转换为 bool false 并且当空数组时(在 D 中)?

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

【问题讨论】:

  • 为什么没人给问题评分,我不明白
  • @Quonux:第一个猜测:因为 D 不是脚本语言...

标签: string d implicit-conversion boolean-logic


【解决方案1】:

编译器将条件和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 属性是否相等,因此根据 is 运算符,""null 不会相同,以及特定的空数组是否具有 @ 987654346@ ptr 取决于其值的设置方式。因此,数组为空这一事实并不能说明它是否为null。您必须与is 运营商核实才能确定。

所有这一切的结果是,将数组(或字符串)直接置于您正在使用的条件中通常是不好的做法

if(x) {...}

相反,您应该清楚自己正在检查的内容。你在乎它是否是空的吗?在这种情况下,您应该检查任一

if(x.empty) {...}

if(x.length == 0} {...}

或者你真的在乎它是null吗?在这种情况下,请使用is 运算符:

if(x is null) {...}

数组在条件中的行为与语言的其余部分一致(例如,检查指针和引用类型以查看它们是否为null),但不幸的是,实际上,数组的这种行为是相当的容易出错。因此,我建议您永远不要将数组本身置于 if 语句或循环的条件中。

【讨论】:

    【解决方案2】:

    数组的默认转换看.ptr,这意味着只有默认初始化的数组(或显式设置为null)评估为false

    作为附加效果,D 中的字符串文字是 \0 终止的,这意味着 ("")[0] == '\0' 并且因此 ("").ptr 不能为空(这会导致段错误)

    IMO 它应该查看长度,您可以在需要时使用 ptr

    【讨论】:

      【解决方案3】:

      当我尝试它时它会...

      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 中的许多其他上下文中是可以互换的。

      【讨论】:

      • 我认为空的非空字符串也隐式转换为false。我一直认为不包含任何信息的类型实例应该隐式转换为false。只是出于好奇......在什么情况下你想要这样的行为?
      • 这是因为指针 - 乔纳森的回答对此进行了更详细的说明。你为什么要它?嗯,idk,我从不使用 if(x)。有时我确实想知道它是否为空 - 想想 null 表示用户从未输入任何信息的情况,而“”表示他们完成了表单,但故意将其留空。这有时很有用。但是 if(x) 有点奇怪,所以我更喜欢 if(x is null) 来准确检查。
      • 好的。我买了,null 映射到“未定义”,"" 映射到零/空。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多