在没有引用其内存位置的情况下,对class
而不是struct
变量进行复制的最佳方法是什么。
例如
class Person {
var name: String = ""
var age: Int = 0
init(name: String, age: Int) {
self.name = name
self.age = age
}
var mapped: [String: Any] {
return [
"name": self.name,
"age": self.age
]
}
}
var person: Person = Person(name: "Hitchhiker", age: 42)
var personCopy = person
var dictionary: [String: Any] {
return [
"a_person": person.mapped,
"c_personCopy": personCopy.mapped
]
}
print("Original:", dictionary.jsonStringValue)
person.age = 100
person.name = "Guide"
print("\n\n========\n\n")
print("Edit 1:", dictionary.jsonStringValue)
personCopy.age = 200
personCopy.name = "To the Galaxy"
print("\n\n========\n\n")
print("Edit 2:", dictionary.jsonStringValue)
// I have this swift extension to make my logs better, don't mind the implicit unwrapping.
extension Dictionary {
var jsonStringValue: String {
let jsonData = try! JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
return String(data: jsonData, encoding: String.Encoding.utf8)!
}
}
这会打印一个如下所示的输出。
Original: {
"a_person" : {
"name" : "Hitchhiker",
"age" : 42
},
"c_personCopy" : {
"name" : "Hitchhiker",
"age" : 42
}
}
========
Edit 1: {
"a_person" : {
"name" : "Guide",
"age" : 100
},
"c_personCopy" : {
"name" : "Guide",
"age" : 100
}
}
========
Edit 2: {
"a_person" : {
"name" : "To the Galaxy",
"age" : 200
},
"c_personCopy" : {
"name" : "To the Galaxy",
"age" : 200
}
}
如果我操纵副本的值,原件也会更新,因为副本是通过引用分配的。
我知道我可以创建类似于扩展函数的东西,它会生成原始变量的copy
,就像这样。
extension Person {
func copy() -> Person {
return Person(name: self.name, age: self.age)
}
}
var person = Person(name: "Jon Snow", age: 0)
var personCopy = person.copy()
personCopy.name = "Jon Targaryen" // this is now a value copy.
但是,如果不为许多不同的模型创建大量的样板代码,我怎么能这样做呢?
更新:
我知道我可以在这里使用 Swift Protocols ,例如
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
我在这个answer中看到了,但是我必须将我的Model类子类化为这些,这可能会导致一些问题,因为我的Model已经是一个子类,它希望我实现一些这些样板< strong>初始化程序,我不想要那个
答案 0 :(得分:2)
类是引用类型。获取副本的唯一方法是定义copy
方法,或者创建一个init
方法,该方法需要复制另一个实例(与copy
基本相同法)。
只要您不需要继承,就应该考虑将模型类设为struct
而不是class
。然后你会自动获得复制语义。