<div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">For the capture part, it is by strong reference as document says:</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">“By default, a closure expression captures constants and variables from its surrounding scope with strong references to those values. You can use a capture list to explicitly control how values are captured in a closure.”<br>from: Apple Inc. “The Swift Programming Language (Swift 3 beta)”。 iBooks. <a href="https://itun.es/us/k5SW7.l">https://itun.es/us/k5SW7.l</a></blockquote></div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Zhaoxin</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 24, 2016 at 5:07 PM, Tyler Fleming Cloutier via swift-users <span dir="ltr"><<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">The Swift Programming Language book states:<div><br></div><div>"<span style="color:rgb(65,65,65);font-family:Helvetica,Arial,sans-serif;background-color:rgb(249,249,249)">Reference counting only applies to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.</span><font color="#414141" face="Helvetica, Arial, sans-serif">”</font></div><div><br></div><div>However consider the following example.</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#ba2da2">func</span><span> makeIncrementer() -> (() -> </span><span style="color:#703daa">Int</span><span>, () -> </span><span style="color:#703daa">Int</span><span>) {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">var</span><span> runningTotal = </span><span style="color:#272ad8">0</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">func</span><span> incrementer() -> </span><span style="color:#703daa">Int</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> runningTotal += </span><span style="color:#272ad8">1</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">return</span><span> runningTotal</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> }</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">func</span><span> incrementer2() -> </span><span style="color:#703daa">Int</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> runningTotal += </span><span style="color:#272ad8">1</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">return</span><span> runningTotal</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> }</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(49,89,93)"><span style="color:#000000"> </span><span style="color:#ba2da2">return</span><span style="color:#000000"> (</span><span>incrementer</span><span style="color:#000000">, </span><span>incrementer2</span><span style="color:#000000">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(49,89,93)"><span style="color:#ba2da2">let</span><span style="color:#000000"> x = </span><span>makeIncrementer</span><span style="color:#000000">()</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:#4f8187">x</span><span style="color:#000000">.</span><span style="color:#272ad8">0</span><span style="color:#000000">() </span><span>// 1</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#4f8187">x</span><span>.</span><span style="color:#272ad8">1</span><span>() </span><span style="color:#008400">// 2</span></div></div><div><br></div><div>Clearly runningTotal is captured by reference by both incrementer and incrementer2. Is closure capturing the only case in which value types are treated as reference types?</div><div><br></div><div>Why wouldn’t Swift be implement so that runningTotal was Captured as a static copy at the time of capture so that each of the incrementer functions has their own “value”?</div><div><br></div><div>It seems like you could pretty easily run into a retain cycle with a struct even though it is a value type!</div><div><br></div><div>Consider:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#ba2da2">struct</span><span> MyValueType {</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">var</span><span> x: () -> ()</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">init</span><span>() {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#ba2da2">self</span><span>.</span><span style="color:#4f8187">x</span><span> = {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> </span><span style="color:#3e1e81">print</span><span>(</span><span style="color:#ba2da2">self</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span> }</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span> </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;line-height:normal"><span><div style="font-family:Helvetica;font-size:12px">One might imagine that the capture of a value type like MyValueType would make a static copy of self for the closure, but if I understand correctly I actually just get a retain cycle. But it’s even worse, because (as I understand it) whether I do or not is optimization dependent!</div><div style="font-family:Helvetica;font-size:12px"><br></div><div>"<span style="font-family:Helvetica,Arial,sans-serif;font-size:12px;color:rgb(65,65,65);background-color:rgb(249,249,249)">As an optimization, Swift may instead capture and store a </span><em style="font-family:Helvetica,Arial,sans-serif;font-size:12px;border:0px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:rgb(65,65,65)">copy</em><span style="font-family:Helvetica,Arial,sans-serif;font-size:12px;color:rgb(65,65,65);background-color:rgb(249,249,249)"> of a value if that value is not mutated by a closure, and if the value is not mutated after the closure is created.</span><font color="#414141" face="Helvetica, Arial, sans-serif">”</font></div><div style="font-family:Helvetica;font-size:12px"><span style="color:rgb(65,65,65);font-family:Helvetica,Arial,sans-serif;background-color:rgb(249,249,249)"><br></span></div><div style="font-family:Helvetica;font-size:12px">Now it turns out that as of SE-0035 I get an error for the above code. Namely,</div><div style="font-family:Helvetica;font-size:12px"><br></div><div style="font-family:Helvetica;font-size:12px">“Closure cannot implicitly capture a mutating self parameter.”</div><div style="font-family:Helvetica;font-size:12px"><br></div><div style="font-family:Helvetica;font-size:12px">Kind of a strange error message for two reasons. The first is that nothing appears to be doing any mutating or declaring an intention of mutating. The second is that it’s not clear at all (to me at least) how to go about remedying the issue.</div><div style="font-family:Helvetica;font-size:12px"><br></div><div style="font-family:Helvetica;font-size:12px">If I capture self explicitly with something like [s = self], am I getting a copy of self or a reference to self? I would assume a copy of self, but that’s not super clear given the somewhat surprising behavior of capturing value types by reference.</div><div style="font-family:Helvetica;font-size:12px"><br></div><div style="font-family:Helvetica;font-size:12px">I would think the following would be a valid solution. Is there a better one? </div><div style="font-family:Helvetica;font-size:12px"><br></div><div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#ba2da2">struct</span><span> MyValueType {</span></div><p style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"><span> </span><br></p><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> </span><span style="color:#ba2da2">var</span><span> x: (() -> ())!</span></div><p style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"><span> </span><br></p><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> </span><span style="color:#ba2da2">init</span><span>() {</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> </span><span style="color:#ba2da2">self</span><span>.</span><span style="color:#4f8187">x</span><span> = </span><span style="color:#ba2da2">nil</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> </span><span style="color:#ba2da2">self</span><span>.</span><span style="color:#4f8187">x</span><span> = { [s = </span><span style="color:#ba2da2">self</span><span>] </span><span style="color:#ba2da2">in</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> </span><span style="color:#3e1e81">print</span><span>(s)</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> }</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span> }</span></div><p style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"><span> </span><br></p><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>}</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal">Is there a way to use currying to be more explicit about the semantics of passing a value into a closure?</div></div><div style="margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">Any help or discussion would be much appreciated!</div><span class="HOEnZb"><font color="#888888"><div style="margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">Tyler</div></font></span></span></div><div><br></div><div><br></div></div><br>_______________________________________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-users</a><br>
<br></blockquote></div><br></div>