我想使用Dart 2克隆一个复杂的对象(复制值),而不是引用。
示例:
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();
}
这样做的最佳方式是什么?(最佳做法)?
更新说明:此How can I clone an Object (deep copy) in Dart?是在一段时间之前发布的。这里的重点是了解进行了许多改进的Dart 2是否具有复制复杂对象的功能。
答案 0 :(得分:1)
有了您在这里向我们展示的课程,没有什么比
Person p2 = Person()
..name = p1.name
..surname = p1.surname
..city = (City()..name = p1.city.name..state = p1.city.state);
如果将clone
方法添加到Person
和City
,那么显然可以使用它。
该语言没有内置功能可让您复制对象的状态。
我建议至少通过添加构造函数来更改类:
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);
}
然后您可以通过编写以下内容来克隆:
Person P2 = Person(p1.name, p1.surname, City(p1.city.name, p1.city.state));
(还有ob-link的名字)
我说没有复制对象的语言功能,但是实际上,如果您可以访问dart:isolate
库,则存在复制对象的功能:通过隔离的通信端口发送对象。我不建议您使用该功能,但这是为了完整性:
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;
}
同样,我不建议您使用这种方法。 它适用于像这样的简单对象,但不适用于所有对象(并非所有对象都可以通过通信端口发送,例如,一等函数或任何包含一等函数的对象)。
编写类以支持所需的操作,包括复制。
答案 1 :(得分:1)
如前所述,没有内置的解决方案,但是如果要实现不可变的值类型,则可以选中built_value。
https://medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4
答案 2 :(得分:0)
我注意到使用Map.from()
进行浅拷贝而不是深拷贝。
要对包含注释类的Map的类进行深层复制,一种解决方案是使用命名的构造函数
class MyClassB {
int myVar;
// Constructor
MyClassB(this.id);
// Named Constructor to do a deep clone
MyClassB.clone(MyClassB b){
id = b.id;
}
}
class MyClassA {
Map<int,MyClassB> mapOfClassB;
// Constructor
MyClassA(this.myClassB)
// Named constructor to do a deep clone
MyClassA.clone(MyClassA a){
Map<int,myClassB> m = {};
myClassB = a.mapOfClassB.forEach((k,v)=> m[k] = MyClassB.clone(v)); // Use the clone constructor here, if not the maps in MyClassA and MyClassB will linked
}
}
main() {
var b1 = MyClassB(20);
var a1 = MyClassA({0:b1});
var a2 = MyClass1A.clone(a1);
a2.mapOfClassB[0].id = 50;
print(a1.mapOfClassB[0].id); // Should display 20
print(a2.(a1.mapOfClassB[0].id) // Should display 50
}
答案 3 :(得分:0)
我的更简单解决方案只是让clone()
返回具有当前值的新Person
:
class Person {
String name;
String surname;
City city;
Person(this.name, this.surname, this.city);
clone() => Person(name, surname, city);
}
您可能还需要递归地克隆Person
中的对象。例如,通过在clone()
中创建类似的City
函数并将其在此处用作city.clone()
。
对于字符串,您将需要检查其行为或创建/添加一种清理它们的方法。