我有以下课程:
class Client {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let wrongClient = Client(name: "John", age: 9)
如何以适当的年龄创建wrongClient
的新版本?
我想要以下内容:
let rightClient = Client(wrongClient, age: 42)
例如,OCaml允许开发人员执行以下操作:
type client = {
name : string;
age : int;
}
let wrong_client = {name = "John"; age = 25}
let right_client = {wrong_client with age = 42}
或者在Scala中:
case class Client(name: String, age: Int)
val wrongClient = Client(name: "John", age: 9)
val rightClient = wrongClient.copy(age=42)
修改
我想尝试使用Swift进行数据不变性和数据共享。
因为不可变数据意味着"生成"其他值的值,"复制"对象经常发生。所以我的问题是:如何使用Swift轻松地从其他对象构造新对象?
编辑2
我目前正在关注Swiftz' lenses。
答案 0 :(得分:3)
您可以将客户端实现为struct
而不是class
,因为struct
始终按值传递。
struct Client {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
var wrongClient = Client(name: "John", age: 18)
var rightClient = wrongClient
rightClient.age = 99
将wrongClient分配给rightClient会创建一个副本。当您更新rightClient的age
时,wrongClient仍然是18.
答案 1 :(得分:1)
您可以添加其他init
方法。
required init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init(from: Client, withAge: Int) {
self.init(name: from.name, age: withAge)
}
答案 2 :(得分:1)
没有任何明确的简写。我建议像:
class Client {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
private init(from: Client, age:Int) {
self.name = from.name
self.age = age
}
func withAge(age:Int) -> Client {
return Client(from: self, age: age)
}
}
let right_client = Client(name: "John", age: 9)
let wrong_client = right_client.withAge(42)
答案 3 :(得分:1)
必须有更好的方法,但我目前的解决方案是:
init(name: String, age: Int) {
self.name = name
self.age = age
}
init(from: Client, name: Int? = nill, age: Int? = nil) {
self.name = name ?? Client.name
self.age = age ?? Client.age
}
答案 4 :(得分:0)
如果您需要数组的副本,只需使用过滤器并使用总是如下的内容:
let oldTagValueKey = self.tagValueKey.filter({ $0.value.characters.isEmpty == false })
答案 5 :(得分:0)
以下是一个完全符合 NSCopying 协议的 Person 类示例:
class Person: NSObject, NSCopying {
var firstName: String
var lastName: String
var age: Int
init(firstName: String, lastName: String, age: Int) {
self.firstName = firstName
self.lastName = lastName
self.age = age
}
func copy(with zone: NSZone? = nil) -> Any {
let copy = Person(firstName: firstName, lastName: lastName, age: age)
return copy
}
注意 copy(with:) 是通过使用当前人的信息创建一个新的 Person 对象来实现的。
完成后,您可以像这样测试您的复制:
let paul = Person(firstName: "Paul", lastName: "Hudson", age: 36)
let sophie = paul.copy() as! Person
sophie.firstName = "Sophie" sophie.age = 6
print("\(paul.firstName) \(paul.lastName) is \(paul.age)")
print("\(sophie.firstName) \(sophie.lastName) is \(sophie.age)")
来源:https://www.hackingwithswift.com/example-code/system/how-to-copy-objects-in-swift-using-copy