<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>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. </div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">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...</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">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. </div><div id="AppleMailSignature"><br>Andy</div><div><br>On Dec 19, 2016, at 10:43 AM, Nick Keets <<a href="mailto:nick.keets@gmail.com">nick.keets@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div>
<title></title>
<div name="messageBodySection">You are probably asking for a generic solution, but for a specific struct you can implement it like this:
<div><br></div>
<div>
<p style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);"><span style="font-variant-ligatures: no-common-ligatures">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">Person</span> <span style="font-variant-ligatures: no-common-ligatures; color: #000000">{</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> </span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">func</span> <span style="font-variant-ligatures: no-common-ligatures">with(name:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa">String</span><span style="font-variant-ligatures: no-common-ligatures">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">nil</span><span style="font-variant-ligatures: no-common-ligatures">, address:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa">String</span><span style="font-variant-ligatures: no-common-ligatures">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">nil</span><span style="font-variant-ligatures: no-common-ligatures">, phone:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa">String</span><span style="font-variant-ligatures: no-common-ligatures">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">nil</span><span style="font-variant-ligatures: no-common-ligatures">) -></span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">Person</span> <span style="font-variant-ligatures: no-common-ligatures">{</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> </span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">let</span> <span style="font-variant-ligatures: no-common-ligatures">name = name ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">self</span><span style="font-variant-ligatures: no-common-ligatures">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">name</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> </span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">let</span> <span style="font-variant-ligatures: no-common-ligatures">address = address ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">self</span><span style="font-variant-ligatures: no-common-ligatures">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">address</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> </span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">let</span> <span style="font-variant-ligatures: no-common-ligatures">phone = phone ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">self</span><span style="font-variant-ligatures: no-common-ligatures">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">phone</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> </span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187">Person</span><span style="font-variant-ligatures: no-common-ligatures">(name: name, address: address, phone: phone)</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures"> }</span></p>
<p style="margin: 0px; line-height: normal; font-family: Menlo;"><span style="font-variant-ligatures: no-common-ligatures">}</span></p>
</div>
<div><span style="font-variant-ligatures: no-common-ligatures"><br></span></div>
</div>
<div name="messageReplySection"><br>
On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>, wrote:<br>
<blockquote type="cite" style="margin: 5px 5px; padding-left: 10px; border-left: thin solid #1abc9c;">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.<br>
<br>
What's I'm looking for is something like this (not necessarily with this syntax):<br>
<br>
struct Person {<br>
let name: String<br>
let address: String<br>
let phone: String<br>
}<br>
<br>
func f() {<br>
let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, CA", phone: "1234567")<br>
let chris = andy.with(name: "Chris")<br>
let dave = andy.with(address: "50 Townsend St., San Francisco, CA")<br>
}<br>
<br>
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.<br>
<br>
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.<br>
<br>
Anyone taken a look at this before? Any suggestions?<br>
<br>
Andy<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote>
</div>
</div></blockquote></body></html>