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.
Something like:- ```var newObject = Random object. clone(oldObject) will return a copied instance.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With