0

This doesn't change the value of 'myStuff.stuff', its value is still 'start' :

void main() {

 Thing myStuff = Thing();
 myStuff.stuff = 'start';
 doStuff(myStuff);
 print(myStuff.stuff);

}

void doStuff(Thing theStuff) {
 theStuff = Thing();
 theStuff.stuff = 'test';
}

class Thing {
 String stuff = '';
}

How can I replace the referenced object in a function ?

ouai
  • 150
  • 1
  • 10

1 Answers1

2

You cannot do this in the method that you show. Dart is not pass by reference. It is pass by value.

If you want to be able to do something similar to this, you can either wrap your Thing object with a another object or provide a callback that modifies your original object.

Something along these lines for the wrapper class method:

void main() {
  Thing myStuff = Thing();
  myStuff.stuff = 'start';
  
  ThingWrap wrapper = ThingWrap();
  wrapper.thing = myStuff;
  
  doStuff1(wrapper);
  
  print(wrapper.thing.stuff);
}

void doStuff1(ThingWrap theStuff) {
 var newStuff = Thing();
 newStuff.stuff = 'test';
  
  theStuff.thing = newStuff;
}

class Thing {
 String stuff = '';
}

class ThingWrap {
  Thing thing = Thing();
}

or the callback method:

void main() {
  Thing myStuff = Thing();
  myStuff.stuff = 'start';
  
  doStuff1((newVal) {
    myStuff = newVal;
  });
  
  print(myStuff.stuff);
}

void doStuff1(Function(Thing) callback) {
  var newStuff = Thing();
  newStuff.stuff = 'test';
  callback(newStuff);
}

class Thing {
 String stuff = '';
}

It's not immediately clear why you would want to do this based on the example you provided. If this were provided, it may have been possible to provide a cleaner solution. Simply providing a return value for doStuff and assigning it to myStuff in main would seem like the obvious way to do the same thing.

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
  • Dart is pass by reference for objects, you just proved it here with your wrapper. If you comment the line theStuff = Thing(); from my original post, same thing. What I want to know is if it's possible to replace the content of the reference. Change the content stored at the memory adress of myStuff without having to do something convoluted like you explain in your post. – ouai Jul 13 '21 at 10:21
  • As to why I want to do this : the standard fromJson method used by the dart:convert package returns an objet. I'd like to affect that object into an existing variable. – ouai Jul 13 '21 at 10:24
  • @ouai You don't quite understand the term "pass-by-reference". Like Java, Dart is pass by value for *everything*, and for objects, it can be thought of as passing-references-by-value, like a pointer in C. See [this](https://stackoverflow.com/questions/25170094/what-is-the-true-meaning-of-pass-by-reference-in-modern-languages-like-dart). Some languages are truly pass-by-reference and would allow to do what you're trying to do in your example in your question, but Dart is not. If Dart were truly pass-by-reference, your example in your question would work perfectly as you want. – Christopher Moore Jul 13 '21 at 12:23
  • @ouai And please clarify again why you want to do this; I did not find your explanation clear. There is no `fromJson` method in `dart:convert` AFAIK, so please link it if there is. And I'm not sure what "I'd like to affect that object into an existing variable." means exactly. – Christopher Moore Jul 13 '21 at 12:25
  • Ok, this pass-by-reference stuff is the explanation I was looking for, thanks :) – ouai Jul 13 '21 at 18:59
  • The json.decode method, which you can find in the dart:convert package, automatically calls the static fromJson method if it exists for a given class. However, theses fromJson method (to my knowledge) have to return an object. Which is problematic if I want to deserialise my json INTO an existing object. But clearly in this case, I need to rethink the process and adapt it to Dart. – ouai Jul 13 '21 at 19:02
  • @ouai Why do you think that `json.decode` calls `fromJson` internally? – Christopher Moore Jul 13 '21 at 19:14
  • My bad, it only calls toJson. Flutter.dev recommends the use of a fromJson constructor which you either build yourself (or you use json_serializable). – ouai Jul 14 '21 at 17:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234868/discussion-between-christopher-moore-and-ouai). – Christopher Moore Jul 14 '21 at 17:57
  • @ChristopherMoore How did your first method work? I am very confused about this. Can I avoid this? I mean, I modified `doStuff1` function like this. Still original value is change. how is it work? ```void doStuff1(ThingWrap theStuff) { ThingWrap _theStuff = theStuff; var newStuff = Thing(); newStuff.stuff = 'test'; _theStuff.thing = newStuff; }``` – BIS Tech Sep 17 '22 at 04:56
  • @BISTech You're doing `ThingWrap _theStuff = theStuff;`. This makes `_theStuff` a reference to the same object as `theStuff`. Any modifications to `_theStuff` are the same as doing those modifications to `theStuff` after that assignment. – Christopher Moore Sep 17 '22 at 19:03