Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clone (copy values) a complex object in Dart 2

Tags:

dart

I would like to clone a complex object (copy values), not referencing, using Dart 2.

Example:

class Person {
  String name;
  String surname;
  City city;
}

class City {
  String name;
  String state;
}

main List<String> args {
  City c1 = new City()..name = 'Blum'..state = 'SC';
  Person p1 = new Person()..name = 'John'..surname = 'Xuebl'..city = c1;


  Person p2 = // HERE, to clone/copy values... Something similar to p1.clone();
}

What would be the way (best practice) to do this?

Update note: This How can I clone an Object (deep copy) in Dart? was posted some time ago. The focus here is to understand if Dart 2 that is bringing many improvements, has a facility for copying complex objects.

like image 498
Muka Avatar asked Jul 15 '18 22:07

Muka


People also ask

How do you make a copy of an object in darts?

Something like:- ```var newObject = Random object. clone(oldObject) will return a copied instance.

What is the difference between a shallow copy and a deep copy?

1. In Shallow copy, a copy of the original object is stored and only the reference address is finally copied. In Deep copy, the copy of the original object and the repetitive copies both are stored.


3 Answers

With the classes you have shown us here, there is nothing shorter than

Person p2 = Person()
  ..name = p1.name
  ..surname = p1.surname
  ..city = (City()..name = p1.city.name..state = p1.city.state);

If you add a clone method to Person and City, then you can obviously use that. There is nothing built in to the language to allow you to copy the state of an object.

I would recommend changing the classes, at least by adding a constructor:

class Person {
  String name;
  String surname;
  City city;
  Person(this.name, this.surname, this.city);
}
class City {
  String name;
  String state;
  City(this.name, this.state);
}

Then you can clone by just writing:

Person P2 = Person(p1.name, p1.surname, City(p1.city.name, p1.city.state));

(And ob-link about names)

I say that there is no language feature to copy objects, but there actually is, if you have access to the dart:isolate library: Sending the object over a isolate communication port. I cannot recommend using that feature, but it's here for completeness:

import "dart:isolate";
Future<T> clone<T>(T object) {
  var c = Completer<T>();
  var port = RawReceivePort();
  port.handler = (Object o) {
    port.close();
    c.complete(o);
  }
  return c.future;
}

Again, I cannot recommend using this approach. It would work for simple objects like this, but it doesn't work for all objects (not all objects can be sent over a communication port, e.g., first-class functions or any object containing a first class function).

Write your classes to support the operations you need on them, that includes copying.

like image 154
lrn Avatar answered Oct 13 '22 15:10

lrn


My simpler solution just let clone() return a new Person with the current values:

class Person {
  String name;
  String surname;
  City city;
  Person(this.name, this.surname, this.city);
  clone() => Person(name, surname, city);
}

You might further need to recursively clone the objects in your Person. as an example by creating a similar clone() function in the City and using it here as city.clone().
For the strings you will need to check their behavior or also create / add a way for cleaning them.

like image 36
a.l.e Avatar answered Oct 13 '22 16:10

a.l.e


As said, there is no built in solution for that, but if the ideia is to accomplish immutable value types you can check built_value.

https://medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4

like image 21
Leo Cavalcante Avatar answered Oct 13 '22 16:10

Leo Cavalcante