I would like to pass a primitive (int, bool, ...) by reference. I found a discussion about it (paragraph "Passing value types by reference") here: value types in Dart, but I still wonder if there is a way to do it in Dart (except using an object wrapper) ? Any development ?
-
I'm curious, what is your use case? Why do you want to do this? – Shailen Tuli Aug 16 '13 at 03:06
-
I am sorry, but I don't understand the comment. I'm simply trying to understand the intent of the questioner. – Shailen Tuli Aug 16 '13 at 07:37
-
I am not surprised (curious) that someone needs it. Also, I'm not surprised that is missing in the Dart language. It is useful, but not critical. – mezoni Aug 16 '13 at 08:49
-
@mezoni Understanding why someone wants to do something allows for suggesting alternative means of achieving the same effect. – Pixel Elephant Aug 16 '13 at 15:25
-
1@ShailenTuli I'm curious too. I used a wrapper and the thing was done, but I wonder if the Dart team has a plan to let us decide when we want a copy or a reference, whatever we use object or primitive. – Eric Lavoie Aug 16 '13 at 15:30
-
@EricLavoie Dart team has a plan to let us decide what we want? Dart team never has a plans to let us decide what we want. Here are the most interesting list of features on which you can not influence and you cannot decide use it or not. Support non-nullable types * Enhancement: Enum * Support for "await" in Dart * Support declaration of generic type for methods * Value types. Also many other useful and interesting issues. All ignored by the Dart team. – mezoni Aug 16 '13 at 15:56
-
@PixelElephant Alternative means of achieving the same effect is not the same as primary question. Please re-read primary question. It very clear and unambiguous question. This is a reasonable question. I did not find anything strange in it. The man's not asking him to convince. He just needed an answer. He had no doubt when asked a question. I do not speak English and still understood exactly what he wants. I (and others) have given an alternative answer, but it is not the answer to primary question. It's more like a advice (useless in this case). – mezoni Aug 16 '13 at 16:08
-
@mezoni I'm not sure if I expressed myself correctly. I meant include an instruction in Dart that will give power to the programmer... If I did understand you well, you meant: Dart will never be C (was not the intention). – Eric Lavoie Aug 16 '13 at 16:18
-
@EricLavoie Why compare with C language? C# language allow pass parameters by reference. But C# produce managed (MSIL) code but not native as C. C# does not have a reference type, but it is possible to pass parameter by the reference. Feel the difference? – mezoni Aug 16 '13 at 16:28
-
duplicate of https://stackoverflow.com/questions/12080422/code-equivalent-of-out-or-reference-parameters-in-dart , see also https://code.google.com/p/dart/issues/detail?id=421 – user7610 Aug 22 '14 at 14:43
8 Answers
The Dart language does not support this and I doubt it ever will, but the future will tell.
Primitives will be passed by value, and as already mentioned here, the only way to 'pass primitives by reference' is by wrapping them like:
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
}
If you don't want to do that, then you need to find another way around your problem.
One case where I see people needing to pass by reference is that they have some sort of value they want to pass to functions in a class:
class Foo {
void doFoo() {
var i = 0;
...
doBar(i); // We want to alter i in doBar().
...
i++;
}
void doBar(i) {
i++;
}
}
In this case you could just make i
a class member instead.

- 27,954
- 10
- 75
- 87
-
-
5If you are into generics, sure go ahead. I believe this is the simplest way to explain the point. :) – Kai Sellgren Aug 16 '13 at 12:49
-
Your answer - The Dart language does not support this and I doubt it ever will. What the problem? This is possible to implement this feature in Dart and in Dart2JS. Many proposed features can be implemented and structured for effective compilation into Javascript. The problem in that the Dart team focused on the fixing bugs and web client improvements. I think this would be implemented in future. I not found problems that prevent this. I think that your work is far from compiler design? I am right? – mezoni Aug 16 '13 at 17:10
-
2I never said there were problems. `I doubt` means that I doubt the feature arrives. This is solely an opinion, which I base on what I've heard and seen in the Dart world so far. Dart has a certain group it targets and certain use cases. The feature might arrive in the future or not, and it's pointless to speculate. It's like speculating weather it will be possible to define variance for types. I doubt it will ever be possible, but I can't know that. – Kai Sellgren Aug 16 '13 at 19:17
-
From the link in @Eric’s question: “The absence of pass by value is not due to the interactions with Javascript. It's a core part of the object model. It's the same in Smalltalk, in Ruby, in Java etc. Object are passed by reference.” – Benji XVI Feb 05 '14 at 15:05
They are passed by reference. It just doesn't matter because the "primitive" types don't have methods to change their internal value.
Correct me if I'm wrong, but maybe you are misunderstanding what "passing by reference" means? I'm assuming you want to do something like param1 = 10
and want this value to still be 10
when you return from your method. But references aren't pointers. When you assign the parameter a new value (with = operator), this change won't be reflected in the calling method. This is still true with non-primitive types (classes).
Example:
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 I tried to make my answer more clear, based on the comments, but somehow I can't seem to phrase it right without causing more confusion. Basically, when someone coming from Java says "parameters are passed by reference", they mean what a C/C++ developer would mean by saying "parameters are passed as pointers".

- 3,752
- 1
- 23
- 32
-
@mezoni: Isn't your definition exactly what "passing by reference" means? If parameters were passed by value, fn1() in my example wouldn't work the way it does, would it? – MarioP Aug 16 '13 at 09:07
-
Well, my point was that there aren't any real primitive types in Dart. num, int, double, bool - those are all objects and behave the same as "complex" classes when passed around as parameters. Also, I think we both mean the same thing, just naming it differently. By "pass by reference" I mean the reference to the object is passed around and changes of the object members remain after the funcion returns. Are we on the same page now? :) – MarioP Aug 16 '13 at 09:51
-
If anyone has any idea how I can make this more clear in my answer, feel free to edit it, because I honestly have no idea how I should phrase that. :-/ – MarioP Aug 16 '13 at 10:27
-
@mezoni Ah, now I get it. I am using Java terminology, where "pass by reference" doesn't have the same meaning as in C/C++, for example. I'll edit my answer to reflect that difference, if I can think of a way to not make it even more confusing. :-S – MarioP Aug 16 '13 at 11:11
-
1I thought that "pass by copy/value" meant "send a copy, the original can't be modified" and that "pass by reference" meant "send the object/address itself, it can be modified". – Eric Lavoie Aug 16 '13 at 15:51
-
@EricLavoie Yes. When you pass the parameter by value where value is the reference to object then you pass copy of the reference but not the copy of the object. But this not means that you pass parameter by reference. The reference to object in this case are parameter (value) and you pass it directly (by value). Passing the reference of the reference to object or the reference to primitive value means passing parameter by reference. – mezoni Aug 16 '13 at 16:22
As dart is compiled into JavaScript, I tried something that works for JS, and guess what!? It worked for dart!
Basically, what you can do is put your value inside an object, and then any changes made on that field value inside that function will change the value outside that function as well.
Code (You can run this on 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;
}
Output
Before passing: false
After passing: true

- 316
- 4
- 15
-
6It was about primitive types: int, double, String & etc. You are using hashmap, i.e. wrapper. Your example is faile. – Michael Kanzieper Dec 06 '21 at 17:58
One of the way to pass the variables by reference by using the values in List. As arrays or lists are Pass by reference by default.
void main() {
List<String> name=['ali' ,'fana'];
updatename(name);
print(name);
}
updatename(List<String> name){
name[0]='gufran';
}
Try this one, This one of the simplest way to pass by reference.

- 169
- 9
You can use ValueNotifier
And, you can pass it as ValueListenable to classes or methods that needs to know up-to-date value, but should not edit it:
class Owner {
final theValue = ValueNotifier(true);
final user = User(theValue);
...
}
class User {
final ValueListeneble<bool> theValue;
User(this.theValue);
...
}
It provides more functionality than actually needed, but solves the problem.

- 6,245
- 5
- 25
- 36
-
Is this usage okay? Does it make sense to use ValueNotifier if you are not gonna use Builder. – bounxye Mar 21 '23 at 09:19
If ValueNotifier + ValueListenable do not work for you (you want to make sure the client does not listen to every change of the value, or your package is pure Dart package and thus cannot reference Flutter libraries), use a function:
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());
}
Output will be:
0
1
This approach has memory usage related downside: the obtainer will hold the reference to the owner
, and this, even if owner
is already not referenced, but obtainer
is still reachable, owner
will be also reachable
and thus will not be garbage collected.
If you do not want the downside, pass the smaller container than the entire 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;
}
The usage of FunctionAsObtainer
will still result in holding the owner from garbage collection, but two other options will not.

- 6,245
- 5
- 25
- 36
Just to make it clear:
void main() {
var list1 = [0,1,2];
var modifiedList1 = addMutable(list1, 3);
var list2 = [0,1,2];
var modifiedList2 = addImmutable(list2, 3);
print(list1);
print(modifiedList1);
print(list2);
print(modifiedList2);
}
List<int> addMutable(List<int> list, int element){
return list..add(element);
}
List<int> addImmutable(List<int> list, int element){
return [...list, element];
}
Output:
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2]
[0, 1, 2, 3]
All variables are passed by value. If a variable contains a primitive (int, bool, etc.), that's it. You got its value. You can do with it whatever you want, it won't affect the source value. If a variable contains an object, what it really contains is a reference to that object.
The reference itself is also passed by value, but the object it references is not passed at all. It just stayed where it was. This means that you can actually make changes to this very object.
Therefore, if you pass a List and if you .add() something to it, you have internally changed it, like it is passed by reference. But if you use the spread operator [...list], you are creating a fresh new copy of it. In most cases that is what you really want to do.
Sounds complicated. Isn't really. Dart is cool.

- 31
- 1
- 3