Of course. Thanks for pointing out the obvious solution. This preserves the 
immutability of the struct and doesn't require O(n^2) code for structs with 
large numbers of fields. 

I was thinking of a generic solution - perhaps something like a synthetic 
initializer that does what your solution does. But that may be overkill given 
how relatively easy it is to do this per struct...

On the other hand a generic solution would encourage using immutable structs. I 
wasted too much time trying to solve this, I suspect others would just give up 
and use var, or even classes. 

Andy

> On Dec 19, 2016, at 10:43 AM, Nick Keets <[email protected]> wrote:
> 
> You are probably asking for a generic solution, but for a specific struct you 
> can implement it like this:
> 
> extension Person {
>     func with(name: String? = nil, address: String? = nil, phone: String? = 
> nil) -> Person {
>         let name = name ?? self.name
>         let address = address ?? self.address
>         let phone = phone ?? self.phone
>         return Person(name: name, address: address, phone: phone)
>     }
> }
> 
> 
>> On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution 
>> <[email protected]>, wrote:
>> I like that structs are value types in Swift, this encourages the use of 
>> immutable data. O'Caml has an operator "with" that allows for copying an 
>> existing struct with a change to one field. I looked at Lenses for this 
>> functionality and it seems like a lot to digest for something so simple. I 
>> also tried to implement this using a constructor, or a function, and it was 
>> not obvious how to do so without a lot of code duplication.
>> 
>> What's I'm looking for is something like this (not necessarily with this 
>> syntax):
>> 
>> struct Person {
>> let name: String
>> let address: String
>> let phone: String
>> }
>> 
>> func f() {
>> let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, CA", 
>> phone: "1234567")
>> let chris = andy.with(name: "Chris")
>> let dave = andy.with(address: "50 Townsend St., San Francisco, CA")
>> }
>> 
>> I tried to implement a "with" function like this but default arguments 
>> cannot reference properties of self. Same problem trying to do this in a 
>> constructor.
>> 
>> Obviously it's possible to create an entirely new Person specifying the 
>> values from an existing Person, but this is very tedious with structures 
>> with many properties.
>> 
>> Anyone taken a look at this before? Any suggestions?
>> 
>> Andy
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to