As example I have struct/class:
struct Pet {
var id: String
var name: String
var age: Int
var type: PetType
}
enum PetType: Int {
case cat
case dog
}
Is it possible to write extension to copy SET OF PARAMETERS from one object to another?
Sth like:
var pet1 = Pet(id: "MyCat1", name: "Cookie", age: 4, type: .cat)
let pet2 = Pet(id: "randomCatId", name: "Socks", age: 3, type: .dog)
pet1.copy(from: pet2, valuesOfKeys: [\.name, \.age] )
// after this pet1 will be:
// ("MyCat1", "Socks", 3, .cat)
// instead of
// ("MyCat1", "Cookie", 4, .cat)
if it is not possible, what is the best way copy from one object to another large set of parameters?
This can be achieved with parameter packs.
First we write a method that copies one key path only:
func copy<T, Value>(from src: T, to dest: inout T, keyPath: WritableKeyPath<T, Value>) {
dest[keyPath: keyPath] = src[keyPath: keyPath]
}
Then, we can write a method that takes a tuple of key paths, all of them can be key paths to different types of values, and repeatedly call the above method.
func copy<T, each Value>(from src: T, to dest: inout T, keyPaths: (repeat WritableKeyPath<T, each Value>)) {
repeat copy(from: src, to: &dest, keyPath: each keyPaths)
}
This means that you should use a tuple instead of an array literal when calling the method:
copy(from: pet2, to: &pet1, keyPaths: (\.name, \.age))