as shown in the code below:
struct Person {
var name: String
}
struct Group {
var person: Person
func callAsFunction() -> Person {
// Person is immutable value
person
}
}
var james = Person(name: "James")
var group = Group(person: james)
group().name = "Wong" //ERROR: Cannot assign to property: function call returns immutable value
group() return an immutable value, that can't be changed! So Is there any way to make the callAsFunction() method return a mutable value?
Thanks ;)
Updated:
My idea is to transfer all the calls and visits of the Group to the Person object in the Group, just like using Person directly.
I can't use dynamicMemberLookup because I don't know what method or property there will be in Person. For example, there may be 100 methods and properties in Person (not only one name property as demonstrated), and it is impossible for me to write 100 subscript methods with dynamicMemberLookup.
My needs are a bit like proxy objects in the Ruby language. Accessing an object (Group) actually accesses another object (Person) inside it, as if the Group does not exist.
If Person was a reference type, it would have worked, but not for a value type. And even if you took your value type, and first assigned it to a variable before mutating it, you would only be mutating your copy, not the original.
If you want the behavior you want, you would use a @dynamicMemberLookup as suggested by matt ( 1) and outlined in SE-0195.
You said:
I can't use
dynamicMemberLookupbecause I don't know what method or property there will be inPerson. For example, there may be 100 methods and properties inPerson(not only one name property as demonstrated), and it is impossible for me to write 100 subscript methods withdynamicMemberLookup.
You do not need “100 subscript methods.” It is the motivating idea behind @dynamicMemberLookup, namely that the properties will be determined dynamically. E.g., here is Person with two properties, but Group only has the one @dynamicMemberLookup.
struct Person {
var name: String
var city: String
}
@dynamicMemberLookup
struct Group {
var person: Person
subscript(dynamicMember keyPath: WritableKeyPath<Person, String>) -> String {
get { self.person[keyPath: keyPath] }
set { self.person[keyPath: keyPath] = newValue }
}
}
var group = Group(person: Person(name: "James", city: "New York"))
group.name = "Wong"
group.city = "Los Angeles"
print(group.person) // Person(name: "Wong", city: "Los Angeles")

