【问题标题】:Dart - Pass by value for int but reference for list?Dart - 通过值传递 int 但引用列表?
【发布时间】:2021-04-15 00:25:50
【问题描述】:

在 Dart 中,看看下面的代码,它是对列表“按引用传递”,对整数“按值传递”吗?如果是这种情况,将通过引用/值传递什么类型的数据?如果不是这样,那么导致这种输出的问题是什么?

void main() {
  var foo = ['a','b'];
  var bar = foo;
  bar.add('c');
  print(aoo); // [a, b, c]
  print(bar); // [a, b, c]
  
  var a = 3;
  int b = a;
  b += 2;
  print(a); // 3
  print(b); // 5
}

【问题讨论】:

  • 你实际上并没有在这里传递任何东西。
  • 当您将一个变量的值复制到另一个变量时,您复制的是该变量的值,仅此而已。当你复制一个 int,一个原语时,你复制了 int 的值,但是当你复制一个列表时,你将 一个引用复制到列表中。所以现在你有两个引用,但它们引用的是同一个列表。

标签: dart


【解决方案1】:

因此,在查看值和引用类型之间的差异时,可以回答您提出的问题。

像几乎所有其他编程语言一样,Dart 将两者区分开来。这样做的原因是您将内存分为所谓的堆栈和堆。堆栈速度很快,但非常有限,因此无法容纳那么多数据。 (顺便说一句,如果您在堆栈中存储了太多数据,您将收到堆栈溢出异常,这是该站点名称的来源;))。另一方面,堆速度较慢,但​​可以容纳几乎无限的数据。

这就是为什么你有值和引用类型。值类型是所有原始数据类型(在 Dart 中,所有数据类型都写得很小,如 intbooldouble 等)。它们的值足够小,可以直接存储在堆栈中。另一方面,您拥有可能更大的所有其他数据类型,因此它们无法存储在堆栈中。这就是为什么所有其他所谓的引用类型基本上都存储在堆中,而只有地址或引用存储在堆栈中。

因此,当您将引用类型bar 设置为foo 时,您实际上只是将存储地址从bar 复制到foo。因此,如果您更改存储在该引用下的数据,则似乎您更改了两个值,因为它们具有相同的引用。相反,当您说b = a 时,您不是在传输参考而是实际值,因此如果您对原始值进行任何更改,它不会受到影响。

我真的希望我能帮助回答你的问题:)

【讨论】:

    【解决方案2】:

    在 Dart 中,所有类型都是引用类型。所有参数都按值传递。引用类型的“值”就是它的引用。 (这就是为什么可能有两个变量包含“相同对象” - 只有一个对象,但两个变量都包含对该对象的引用)。您永远不会仅仅通过传递引用来制作对象的副本。 Dart 没有“通过引用传递”,您可以将 变量 作为参数传递(因此被调用的函数可以更改绑定到变量的值,如 C# 的 ref 参数)。

    Dart 根本没有原始类型。 然而(大警告),数字总是(假装是)规范化的,所以程序中只有一个 1 对象。您不能创建 不同 1 对象。在某种程度上,它的行为类似于其他语言的原始类型,但它不是一个。您可以使用int 作为List<int> 的类型参数,不像在Java 中您需要使用List<Integer>,您可以询问int 的身份,如identical(1, 2),您可以调用整数方法喜欢1.hashCode

    【讨论】:

    • 顺便说一句,SendPort.send 确实指的是“原始值”,尽管我不确定它还应该如何称呼它们(“基本值”?)。也许它根本不应该尝试命名/分类它们。
    • 它可能应该说“类似 JSON”的值(数字、布尔值、字符串、null 以及此类列表以及从字符串到此类的映射)。我有时也称它们为“系统类型”或“系统交互类型”,因为字符串和整数用于相当直接地与世界其他地方通信(print 打印一个字符串,I/O 操作期望并产生数字,所以你不能只显示您自己的实现并期望底层系统能够理解它们)。
    【解决方案3】:

    如果要克隆或复制列表

    var foo = ['a', 'b'];
    var bar = [...foo];
    bar.add('c'); 
    print(bar);  // [a, b, c]
    print(foo);  // [a, b]
    
    var bar_two = []; //or init an empty list
    bar_two.addAll([...bar]);
    print(bar_two); // [a, b, c]
    

    参考链接 Clone a List, Map or Set in Dart

    【讨论】:

      猜你喜欢
      • 2012-04-14
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2021-08-15
      • 2018-06-29
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多