“ ==”和“是”运算符在D中到底是什么?

问题描述 投票:0回答:1

[从《用D编程》中,我了解到==运算符需要访问对象,以便在返回布尔值之前评估左右表达式。因此,不适合比较对象是否为null

... ==运算符可能需要查询对象成员的值,并且尝试通过可能为null的变量访问成员将导致内存访问错误。

also

值相等:==运算符出现在整个示例中这本书通过变量的值比较变量。当说两个变量从这个意义上说相等,它们的价值是相等的

所以,让我们尝试以下方法:

import std.experimental.all;

int[] arr = [1, 1, 2, 2, 3];
arr == arr.reverse.array; // --> true

嗯,这是意外的。例如,在Scala中,相同的表达式返回False

检查完arrarr.reverse.array的存储地址后,它变得更加清晰-不会改变。因此,尽管==的结果是合理的,尽管人们希望它比较数组的值而不是它们的地址,对吧?

[现在,让我们尝试is运算符,该运算符用于比较对象引用,并且应用于检查对象是否为null。它也用于比较类变量。

arr is arr.reverse.array; // --> false

我希望它也返回true,因为它比较了引用。这到底是怎么回事?为什么is相反返回false==返回true

d
1个回答
0
投票

==执行比较值。 is比较参考。您的大错误是使用函数reverse

http://dpldocs.info/experimental-docs/std.algorithm.mutation.reverse.html

反向r 原位

强调我的。这意味着它将修改原始内容。

我怀疑您也在检查内存地址错误。如果使用&arr,则在比较局部变量的地址,而不是数组内容。这不会改变,因为它是相同的局部变量,您只是绑定到其他数组。检查.ptr而不是&,您会看到它发生了变化-.array函数总是为其分配一个新数组。

所以==通过,因为反向同时改变了左侧!这不是因为[1,2,3] == [3,2,1],而是因为在调用反向后,[1,2,3]本身被修改为[3,2,1] == [3,2,1]!。

现在,关于这些运算符的实际作用:==检查某种抽象的相等性。这随类型的不同而不同:它可以被成员函数覆盖(这就是为什么在null类上调用它会带来问题),并且经常进行逐成员比较(例如,数组元素或结构块)。

is,另一方面,则简单得多:直接比较变量,更接近抽象的标识概念,但不完全相同(例如int a = 3; int b = 3; assert(a is b);通过,因为两者均为3,但是它是同一身份吗?值类型的模糊cuz。)

[is永远不会调用用户定义的函数,也永远不会成为成员引用,它只会比较位值。

((有趣的是,float.nan is float.nan也会返回true,而==不会,仅是因为它会比较位值。但并非所有nan都具有相同的位值,因此它不能替代mathNaN在数学模块中!)

© www.soinside.com 2019 - 2024. All rights reserved.