Dart int 和 double 被拘留?被相同()特殊对待?

2023-11-25

Dart 两者都有:

  • 相等运算符== and
  • 名为的顶级函数identical().

通过语法的选择,想要使用 Dart 的感觉很自然==操作员的频率高于identical(),我喜欢这样。事实上,平等部分 of the 惯用飞镖指出“在实践中,您很少需要使用”identical().

在最近的一个回答中我关于自定义过滤器的问题之一, 看起来角飞镖赞成使用identical()而不是==当试图确定模型的变化是否已达到稳定状态时。 (我认为,出于效率原因,这对于大型模型来说是有意义的。)

这让我开始思考自己的身份int所以我写了一些测试identical() over ints。虽然我预计那么小ints might be“interned/cached”(例如类似于Java's Integer.valueOf()), 出乎我的意料,我似乎无法生成两个ints 相等但不相同。我得到类似的结果double.

Are int and double值被保留/缓存?或者可能identical()是在特殊对待他们吗?来自 Java 背景的我曾经将 Dart 等同于:

  • ==到Java的equal()方法和
  • identical()Java 的相等性测试==.

但现在看来这是错误的。有人知道发生了什么事吗?


数字经过特殊处理。如果它们的位模式相同,那么它们一定是相同的(尽管这是否包括不同版本的 NaN 仍然存在争议)。

主要原因是期望、内部细节泄露和效率。

期望:用户期望数字相同。 x == y(对于两个整数)但不相同(x,y),这违背了常识。

内部细节泄露:VM使用SMI(SMall Integers)来表示特定范围内的整数(32位机器上为31位,64位机器上为63位)。这些都是规范化的并且总是相同的。公开此内部实现细节会导致结果不一致,具体取决于您运行的平台。

效率:虚拟机希望尽可能地对数字进行拆箱。例如,在方法内部,双精度数经常被移入寄存器。然而,跟踪原始盒子可能既麻烦又困难。

foo(x, y) {
  var result = x;
  while(y-- > 0) {
    result += x;
  }
  return result;
}

假设虚拟机优化了这个函数并移动result进入寄存器(拆箱x正在进行中)。这允许一个紧密的循环,其中result然后进行有效修改。困难的情况发生了,当y是 0。循环不会执行并且foo会回来x直接地。换句话说,以下条件必须为真:

var x = 5.0;
identical(x, foo(x, 0));  // should be true.

如果 VM 已拆箱result方法中的变量foo它需要为它分配一个新的盒子resultidentical因此调用将返回false.

通过修改定义identical所有这些问题都可以避免。它的成本很小identical不过,检查一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dart int 和 double 被拘留?被相同()特殊对待? 的相关文章

随机推荐