Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Dart pass by reference? [duplicate]

Tags:

flutter

dart

In this post: Flutter video_player dispose

I asked how to dispose something so I can re-use it again. The answer provided works correctly but it left me with this question:

why does this code work as intended? eg it disposes the old instance from videoController using oldController

final oldController = videoController;

  WidgetsBinding.instance.addPostFrameCallback((_) async {
    await oldController.dispose();

    _initController(link); //contains reassignment of videoController = VideoController.network(...)
  });

in C or similar languages, a use of pointer is needed (or should I say my preferred way). To pass the reference, assign a new value to it and then take care of the old one.

like image 552
AnsellC Avatar asked Nov 21 '19 01:11

AnsellC


People also ask

Is flutter pass by reference?

You cannot pass a variable by reference. There needs to be separate assignments to _email and _password in your code, because each assignment can only assign to one of them. You can then fiddle with how to choose which assignment to use, but there needs to be two separate assignments somewhere.

What is the difference between passing by value and passing by reference?

Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument.

How are parameters passed in Dart?

Parameters are a mechanism to pass values to functions. Parameters form a part of the function's signature. The parameter values are passed to the function during its invocation. Unless explicitly specified, the number of values passed to a function must match the number of parameters defined.


2 Answers

Sorry that my answer left you with a confusion. Yes, in Dart you work with references to objects, just like in Java. I'll give a short example that should make it clear for you why this code works as intended:

void main() {
  final t = Test(Test());
  t.removeField();
}

class Test {
  Test t;

  Future<void> removeField() async {
    print('current field: $t');

    Future.delayed(Duration(seconds: 2)).then((_) => print('delayed value: $t'));
    t = null;
  }

  Test([this.t]);
}

prints:

current field: Instance of 'Test'
delayed value: null

In this case, field's value is set to null first and then 2 seconds later callback executes. It accesses object's field, but it's already null. But if we make it like this:

    final old = t;
    Future.delayed(Duration(seconds: 2)).then((_) => print('delayed value: $old'));

it prints:

current field: Instance of 'Test'
delayed value: Instance of 'Test'

We stored previous value of the field and passed it to the callback, so it won't access nulled field.

like image 59
Igor Kharakhordin Avatar answered Oct 11 '22 22:10

Igor Kharakhordin


Dart does not support passing by reference. Dart is only passed by value, just like Java. Java also does not support reference passing.

Is Java “pass-by-reference” or “pass-by-value”?
https://stackoverflow.com/a/40523/1737201

Below is a little proof.

void main() {
  // The variable "myVar" is a "lvalue" (storage of value)
  // Now we assign the value to "myVar" via "rvalue" "Object()"
  final myVar = Object();

  // Remember the old value
  final oldObject = myVar;

  // Now we will try to pass by reference.
  // We assume that we will pass the reference of storage ("lvalue")
  // ("myVar" im our case) because we cannot reference the value (pure data)
  // because the value does not contain storage location information.
  tryChangeMyVarByRef(myVar);

  // Check the result passing by reference
  // If storage of value was passed by its reference then changing
  // the value in this storage should have effect.
  assert(!identical(myVar, oldObject));

  // Epic fail because Dart does not support pass by refernce.
  print('WOW, it works!');
}

void tryChangeMyVarByRef(Object referencedStorgeOfValue) {
  // Try change the value stored in referenced storage of value
  referencedStorgeOfValue = Object();
}

EDIT:

The value (or more correct rvalue which means a data whitout any storage) cannot have an address because the value is just a data. In programming impossible to reference the data (because there are no any way to do that) but possible to reference the storage of data (eg. address of variable) because the storage are always has some location rather than data (data only can be stored at some location but not referenced because data can be replaced at any time at this location and thus this cannot be called as reference to data because this can be incorrect after data reassigment would be perfomed but should be only called as reference of some storage of some data).

In the programming the term "pass by reference" means: pass the reference (address of the location) of the value storage (that is, the address of some varibale with any data but not the address of this data). This allows to replace (but not just change) stored data at some location becuase the storage was referenced (address of laocation was known).

Which means only one thing: you pass reference of the variable where some value are stored.

And this does not means the reference of some value as many newbie wrongly think (who never used C or C++ language).

Another important thing is that the in Dart the object (or instances) itself are references because they are boxed (the values was stored in the heap).

This creates illusion that you pass by reference but at the same time you pass by value the reference (where reference as value is passed by value). Pass by value the reference is not the same as pass by reference the reference.

Free advice to newbie: Learn the C or C++ programming languages to find out the difference between the following things:

  • Pass by value the reference
  • Pass by reference the reference

In both cases the value itself is a reference but in first case you pass the value (reference) by value but in second case you pass the value (reference) by reference.

Enjoy!

like image 25
mezoni Avatar answered Oct 11 '22 22:10

mezoni