[英]In swift how to copy a struct with one with only one different field
如果我有一个快速的结构
struct Person {
let firstName: String
let lastName: String
let gender: Gender
let height: Float
let weight: Float
let age: Int
}
如果有一个对象a
类型的Person
,不时地,仅该领域的一个改变,像lastName
当人结婚,年龄当人过了一个生日等,但我并不想创建一个mutating func
为每个字段,我也不想编写很多样板来构造一个新的结构,再次传递所有这些字段。 有没有比这更好的事情了
let newPerson = oldPerson.copy(lastName = "Married")
我知道这是一个非常简洁的scala与case类的功能,但我还没有看到swift中使用的这个功能。 我可以知道如何实现这一目标吗? 你们认为它应该是swift的特色吗? 也许我们可以提出一个快速的进化建议?
我不知道是否有一个优雅的解决方案。 一种选择是定义一个复制方法,该方法为每个属性采用可选参数,默认为当前属性值:
struct Person {
let firstName: String
let lastName: String
let age: Int
func copy(firstName: String? = nil, lastName: String? = nil, age: Int? = nil) -> Person {
return Person(firstName: firstName ?? self.firstName,
lastName: lastName ?? self.lastName,
age: age ?? self.age)
}
}
let john = Person(firstName: "John", lastName: "Doe", age: 29)
let jane = john.copy(firstName: "Jane")
print(jane) // Person(firstName: "Jane", lastName: "Doe", age: 29)
Person
的copy
函数自然可以为其参数设置默认值,这样只允许使用person属性的子集调用它。 问题是我们可能不会使用self
来指代我们希望默认使用的值。 但是,我们可以引用一个类的静态成员(fir方便,比如Person
静态成员),这将允许我们创建一些类似的东西
struct Person {
static var currentObjFirstName: String = ""
static var currentObjLastName: String? = ""
// ...
static var currentObjAge: Int = 0
let firstName: String
let lastName: String?
// ...
let age: Int
init(firstName: String, lastName: String?, age: Int) {
self.firstName = firstName
self.lastName = lastName
self.age = age
}
func prepareCopy() -> Person {
Person.currentObjFirstName = self.firstName
Person.currentObjLastName = self.lastName
Person.currentObjAge = self.age
return self
}
func copy(firstName firstName: String = Person.currentObjFirstName,
lastName: String? = Person.currentObjLastName,
age: Int = Person.currentObjAge) -> Person {
return Person(firstName: firstName, lastName: lastName, age: age)
}
}
用法示例:
let foo = Person(firstName: "foo", lastName: "bar", age: 42)
let bar = foo.prepareCopy().copy(age: 21)
print(bar) // Person(firstName: "foo", lastName: Optional("bar"), age: 21)
let baz = foo.prepareCopy().copy(lastName: nil)
print(baz) // Person(firstName: "foo", lastName: nil, age: 42)
可能这个解决方案在你的描述中作为“...样板来构造一个新的结构再次传递到所有那些领域” ,但除此之外,上面的prepareCopy()
不是很漂亮......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.