151 votes

Comment cloner un objet (copie profonde) dans Dart ?

Existe-t-il un moyen, supporté par le langage, de faire une copie complète (profonde) d'un objet dans Dart ?

Secondaire uniquement ; existe-t-il plusieurs façons de procéder, et quelles sont les différences ?

Merci pour la clarification !

5voto

C xkey Points 1

Dart ne partage pas la mémoire au sein de plusieurs threads (isoler), donc...

extension Clone<T> on T {

  /// in Flutter
  Future<T> clone() => compute<T, T>((e) => e, this);

  /// in Dart
  Future<T> clone() async {
    final receive = ReceivePort();
    receive.sendPort.send(this);
    return receive.first.then((e) => e as T).whenComplete(receive.close);
  }
}

4voto

Aayush Goyal Points 61

Essayer d'utiliser un Copiable interface fournie par Dart.

4voto

adel parsa Points 1

Il existe un moyen plus simple de résoudre ce problème utilisez simplement ... opérateur par exemple, clone une Map

Map p = {'name' : 'parsa','age' : 27};
Map n = {...p};

Vous pouvez également le faire pour les propriétés des classes. Dans mon cas, j'avais besoin de cloner une propriété listée d'une classe. Donc :

class P1 {
List<String> names = [some data];
}

/// codes
P1 p = P1();
List<String> clonedList = [...p.names]
// now clonedList is an unreferenced type

3voto

BadCash Points 566

Il n'y a pas de moyen intégré de cloner profondément un objet - vous devez fournir vous-même la méthode pour le faire.

J'ai souvent besoin de coder/décoder mes classes à partir de JSON, donc je fournis habituellement MyClass fromMap(Map) y Map<String, dynamic> toJson() méthodes. Elles peuvent être utilisées pour créer un clone profond en encodant d'abord l'objet en JSON puis en le décodant en retour.

Cependant, pour des raisons de performance, j'implémente généralement un système séparé de clone à la place. C'est un travail de quelques minutes, mais je trouve que c'est souvent du temps bien utilisé.

Dans l'exemple ci-dessous, cloneSlow utilise la technique JSON, et cloneFast utilise la méthode du clone explicitement implémentée. Les impressions prouvent que le clone est réellement un clone profond, et pas seulement une copie de la référence à a .

import 'dart:convert';

class A{
  String a;
  A(this.a);

  factory A.fromMap(Map map){
    return A(
        map['a']
   );
  }

  Map<String, dynamic> toJson(){
    return {
      'a': a
    };
  }

  A cloneSlow(){
    return A.fromMap(jsonDecode(jsonEncode(this)));
  }

  A cloneFast(){
    return A(
      a
    );
  }

  @override
  String toString() => 'A(a: $a)';
}

void main() {
  A a = A('a');
  A b = a.cloneFast();
  b.a = 'b';

  print('a: $a   b: $b');
}

1voto

Robin Points 21

Un exemple de copie profonde dans dart.

void main() {
  Person person1 = Person(
      id: 1001,
      firstName: 'John',
      lastName: 'Doe',
      email: 'john.doe@email.com',
      alive: true);

  Person person2 = Person(
      id: person1.id,
      firstName: person1.firstName,
      lastName: person1.lastName,
      email: person1.email,
      alive: person1.alive);

  print('Object: person1');
  print('id     : ${person1.id}');
  print('fName  : ${person1.firstName}');
  print('lName  : ${person1.lastName}');
  print('email  : ${person1.email}');
  print('alive  : ${person1.alive}');
  print('=hashCode=: ${person1.hashCode}');

  print('Object: person2');
  print('id     : ${person2.id}');
  print('fName  : ${person2.firstName}');
  print('lName  : ${person2.lastName}');
  print('email  : ${person2.email}');
  print('alive  : ${person2.alive}');
  print('=hashCode=: ${person2.hashCode}');
}

class Person {
  int id;
  String firstName;
  String lastName;
  String email;
  bool alive;
  Person({this.id, this.firstName, this.lastName, this.email, this.alive});
}

Et le résultat ci-dessous.

id     : 1001
fName  : John
lName  : Doe
email  : john.doe@email.com
alive  : true
=hashCode=: 515186678

Object: person2
id     : 1001
fName  : John
lName  : Doe
email  : john.doe@email.com
alive  : true
=hashCode=: 686393765

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