在Dart中有没有一种方法可以通过引用传递一个原语参数?

zf2sa74q  于 2022-12-28  发布在  其他
关注(0)|答案(7)|浏览(224)

我想通过引用传递一个原语(int,bool,...)。我在这里找到了关于它的讨论(段落“通过引用传递值类型”):值类型,但我仍然想知道是否有办法在Dart中做到这一点(除了使用对象 Package 器)?任何发展?

erhoui1w

erhoui1w1#

dart 语言不支持这一点,我怀疑它永远不会支持,但未来会证明一切。
基元将通过值传递,正如这里已经提到的,“通过引用传递基元”的唯一方法是像这样 Package 它们:

class PrimitiveWrapper {
  var value;
  PrimitiveWrapper(this.value);
}

void alter(PrimitiveWrapper data) {
  data.value++;
}

main() {
  var data = new PrimitiveWrapper(5);
  print(data.value); // 5
  alter(data);
  print(data.value); // 6
}

如果你不想这样做,那么你需要找到另一种方法来解决你的问题。
我看到人们需要通过引用传递的一种情况是,他们有某种类型的值要传递给类中的函数:

class Foo {
  void doFoo() {
    var i = 0;
    ...
    doBar(i); // We want to alter i in doBar().
    ...
    i++;
  }

  void doBar(i) {
    i++;
  }
}

在这种情况下,您可以将i设置为类成员。

r6l8ljro

r6l8ljro2#

不, Package 纸是唯一的办法。

lrl1mhuk

lrl1mhuk3#

它们是通过引用传递的,这并不重要,因为"原始"类型没有改变其内部值的方法。
如果我说错了请纠正我,也许你误解了"通过引用传递"的意思?我假设你想做类似param1 = 10的事情,并希望当你从方法返回时这个值仍然是10。但是引用不是指针。当你给参数赋一个新值时(带有=运算符),则此更改不会反映在调用方法中。对于非基元类型(类),这仍然成立。
示例:

class Test {
  int val;
  Test(this.val);
}

void main() {
  Test t = new Test(1);
  fn1(t);
  print(t.val); // 2
  fn2(t);
  print(t.val); // still 2, because "t" has been assigned a new instance in fn2()
}

void fn1(Test t) {
  print(t.val); // 1
  t.val = 2;
}

void fn2(Test t) {
  t = new Test(10);
  print(t.val); // 10
}
    • EDIT**我试图根据注解使我的回答更清楚,但不知何故,我似乎无法正确表达它而不引起更多的混乱。基本上,当来自Java的人说"参数通过引用传递"时,他们的意思就是C/C ++开发人员所说的"参数作为指针传递"。
ajsxfq5m

ajsxfq5m4#

由于dart被编译成JavaScript,我尝试了一些对JS有效的东西,你猜怎么着!?它对dart有效!
基本上,你可以做的是把你的值放在一个对象中,然后在函数中对该字段值所做的任何更改都会同时更改函数外部的值。

代码(您可以在dartpad.dev上运行此代码)

main() {
  var a = {"b": false};
  
  print("Before passing: " + a["b"].toString());
  trial(a);
  print("After passing: " + a["b"].toString());
}

trial(param) {
  param["b"] = true;
}

产出

Before passing: false
After passing: true
hc2pp10m

hc2pp10m5#

使用List中的值通过引用传递变量的方法之一。默认情况下,数组或列表是通过引用传递的。

void main() {
List<String> name=['ali' ,'fana'];
updatename(name);
print(name);
}
updatename(List<String> name){
name[0]='gufran';
}

试试这个,这是通过引用传递的最简单的方法之一.

jq6vz3qz

jq6vz3qz6#

您可以使用ValueNotifier
而且,你可以将它作为ValueListenable传递给需要知道最新值的类或方法,但不应该编辑它:

class Owner {
  final theValue = ValueNotifier(true);
  final user = User(theValue);
  ...
}

class User {
  final ValueListeneble<bool> theValue;
  
  User(this.theValue);

  ...
}

它提供了比实际需要更多的功能,但解决了问题。

ds97pgxw

ds97pgxw7#

如果ValueNotifier + ValueListenable不适合你(你想确保客户端不会监听值的每一个变化,或者你的包是纯Dart包,因此不能引用Flutter库),使用一个函数:

class Owner {
  int _value = 0;

  int getValue() => _value;

  void increase() => _value++;
}

void main() {
  final owner = Owner();
  int Function() obtainer = owner.getValue;

  print(obtainer());
  owner.increase();
  print(obtainer());
}

输出将为:

0
1

这种方法具有与内存使用相关的缺点:获取器将保持对owner的引用,并且即使owner已经没有被引用,但是obtainer仍然是可达的,owner也将是可达的,因此将不被垃圾收集。
如果您不希望出现这种情况,请传递比整个所有者小的容器:

import 'package:flutter/foundation.dart';

class ListenableAsObtainer<T> implements ValueObtainer<T> {
  ListenableAsObtainer(this._listenable);

  final ValueListenable<T> _listenable;

  @override
  T get value => _listenable.value;
}

class FunctionAsObtainer<T> implements ValueObtainer<T> {
  FunctionAsObtainer(this._function);

  final T Function() _function;

  @override
  T get value => _function();
}

class ValueAsObtainer<T> implements ValueObtainer<T> {
  ValueAsObtainer(this.value);

  @override
  T value;
}

/// Use this interface when the client needs
/// access to the current value, but does not need the value to be listenable,
/// i.e. [ValueListenable] would be too strong requirement.
abstract class ValueObtainer<T> {
  T get value;
}

使用FunctionAsObtainer仍然会导致从垃圾收集中保留所有者,但其他两个选项不会。

相关问题