4 votes

Est-ce que Dart passe par référence ?

Dans ce poste : Mise au rebut du lecteur vidéo de Flutter

J'ai demandé comment se débarrasser d'un objet pour pouvoir le réutiliser à nouveau. La réponse fournie fonctionne correctement, mais elle m'a laissé avec cette question :

pourquoi ce code fonctionne-t-il comme prévu ? par exemple, il élimine l'ancienne instance de videoController en utilisant oldController

final oldController = videoController;

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

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

en C ou dans des langages similaires, l'utilisation d'un pointeur est nécessaire (ou devrais-je dire ma façon préférée). Pour passer la référence, il faut lui attribuer une nouvelle valeur et ensuite s'occuper de l'ancienne.

5voto

Igor Kharakhordin Points 5886

Désolé que ma réponse vous ait laissé dans la confusion. Oui, en Dart vous travaillez avec des références à des objets, tout comme en Java. Je vais vous donner un petit exemple qui devrait vous faire comprendre pourquoi ce code fonctionne comme prévu :

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]);
}

des empreintes :

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

Dans ce cas, la valeur du champ est d'abord définie comme nulle, puis 2 secondes plus tard, la fonction de rappel est exécutée. Elle accède au champ de l'objet, mais il est déjà nul. Mais si nous le faisons comme ceci :

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

il imprime :

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

Nous avons stocké la valeur précédente du champ et l'avons passée à la callback, afin qu'elle n'accède pas à un champ annulé.

3voto

mezoni Points 2361

Dart ne supporte pas le passage par référence. Dart ne passe que par valeur, tout comme Java. Java ne supporte pas non plus le passage par référence.

Java est-il "pass-by-reference" ou "pass-by-value" ?
https://stackoverflow.com/a/40523/1737201

En voici une petite preuve.

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 :

La valeur (ou plus exactement rvalue ce qui signifie qu'une donnée (sans stockage) ne peut pas avoir d'adresse car la valeur est juste une donnée. En programmation, il est impossible de référencer les données (parce qu'il n'y a aucun moyen de le faire) mais il est possible de référencer le stockage des données (par exemple, l'adresse d'une variable) parce que le stockage a toujours un certain emplacement plutôt que les données (les données peuvent seulement être stockées à un certain emplacement mais pas référencées parce que les données peuvent être remplacées à tout moment à cet emplacement et donc cela ne peut pas être appelé comme une référence aux données parce que cela peut être incorrect après que la réaffectation des données soit effectuée mais devrait être appelé comme une référence à un certain stockage de certaines données).

Dans la programmation, le terme "passer par référence" signifie : passer la référence (adresse de l'emplacement) de la mémoire de valeur (c'est-à-dire l'adresse d'une certaine varibale avec des données quelconques mais pas l'adresse de ces données). Cela permet pour remplacer (mais pas seulement la modification) des données stockées à un certain endroit parce que le stockage a été référencé (l'adresse de la location était connue).

Ce qui ne signifie qu'une chose : vous passez la référence de la variable où sont stockées certaines valeurs.

Et cela ne signifie pas que le reference of some value comme le pensent à tort de nombreux débutants (qui n'ont jamais utilisé le langage C ou C++).

Une autre chose importante est que dans Dart, les objets (ou instances) eux-mêmes sont des références parce qu'ils sont encadrés (les valeurs sont stockées dans le tas).

Cela crée l'illusion que vous passez par référence mais en même temps vous pass by value the reference (où la référence en tant que valeur est transmise par valeur). Passez by value the reference n'est pas la même chose que pass by reference the reference .

Conseils gratuits aux débutants : Apprenez les langages de programmation C ou C++ pour connaître la différence entre les choses suivantes :

  • Passez by value the reference
  • Passez by reference the reference

Dans les deux cas, la valeur elle-même est une référence, mais dans le premier cas, vous passez la valeur (référence) par valeur et dans le second cas, vous passez la valeur (référence) par référence.

Profitez-en !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X