<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">A closure assigned to a variable is already a named handler…<br>Make it optional and it’s now a cancelable named handler…<br>Put it in a <code style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">defer</code> block and you have exactly what you want, a cancelable named defer handler…</p>
<pre style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-swift" style="font-size:1em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248) none repeat scroll 0% 0%"><span class="hljs-func"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">func</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">doSomething</span><span class="hljs-params">(input: String)</span> -&gt; <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">String</span>? </span>{

    <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// Create a cancelable named defer handler</span>
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">var</span> namedDeferHandler: (() -&gt; <span class="hljs-type" style="color:rgb(68,85,136);font-weight:bold">Void</span>)? = { <span class="hljs-built_in" style="color:rgb(0,134,179)">print</span>(<span class="hljs-string" style="color:rgb(221,17,68)">&quot;It didn&#39;t work, but I&#39;ve taken care of any cleaning up.&quot;</span>) }
    defer { namedDeferHandler?() }

    <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// Check the input</span>
    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">if</span> input == <span class="hljs-string" style="color:rgb(221,17,68)">&quot;&quot;</span> { <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">return</span> <span class="hljs-built_in" style="color:rgb(0,134,179)">nil</span> }

    <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// Cancel the named defer handler</span>
    namedDeferHandler = <span class="hljs-built_in" style="color:rgb(0,134,179)">nil</span>

    <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">return</span> <span class="hljs-string" style="color:rgb(221,17,68)">&quot;It worked!&quot;</span>
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">It’s very flexible, you can have multiple handlers and cancel only some of them, include some non-optional code in the defer block itself, etc.</p>
<div title="MDH:PGRpdj48ZGl2PjxkaXY+PGRpdj48YnI+PC9kaXY+QSBjbG9zdXJlIGFzc2lnbmVkIHRvIGEgdmFy
aWFibGUgaXMgYWxyZWFkeSBhIG5hbWVkIGhhbmRsZXIuLi48YnI+TWFrZSBpdCBvcHRpb25hbCBh
bmQgaXQncyBub3cgYSBjYW5jZWxhYmxlIG5hbWVkIGhhbmRsZXIuLi48YnI+PC9kaXY+UHV0IGl0
IGluIGEgYGRlZmVyYCBibG9jayBhbmQgeW91IGhhdmUgZXhhY3RseSB3aGF0IHlvdSB3YW50LCBh
IGNhbmNlbGFibGUgbmFtZWQgZGVmZXIgaGFuZGxlci4uLjxicj48YnI+PC9kaXY+YGBgc3dpZnQ8
YnI+ZnVuYyBkb1NvbWV0aGluZyhpbnB1dDogU3RyaW5nKSAtJmd0OyBTdHJpbmc/IHs8YnI+PGJy
PiZuYnNwOyZuYnNwOyZuYnNwOyAvLyBDcmVhdGUgYSBjYW5jZWxhYmxlIG5hbWVkIGRlZmVyIGhh
bmRsZXI8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHZhciBuYW1lZERlZmVySGFuZGxlcjogKCgpIC0m
Z3Q7IFZvaWQpPyA9IHsgcHJpbnQoIkl0IGRpZG4ndCB3b3JrLCBidXQgSSd2ZSB0YWtlbiBjYXJl
IG9mIGFueSBjbGVhbmluZyB1cC4iKSB9PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBkZWZlciB7IG5h
bWVkRGVmZXJIYW5kbGVyPygpIH08YnI+PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAvLyBDaGVjayB0
aGUgaW5wdXQ8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IGlmIGlucHV0ID09ICIiIHsgcmV0dXJuIG5p
bCB9PGJyPjxicj4mbmJzcDsmbmJzcDsmbmJzcDsgLy8gQ2FuY2VsIHRoZSBuYW1lZCBkZWZlciBo
YW5kbGVyPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBuYW1lZERlZmVySGFuZGxlciA9IG5pbDxicj48
YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHJldHVybiAiSXQgd29ya2VkISI8YnI+fTxicj5gYGA8YnI+
PGJyPjwvZGl2Pkl0J3MgdmVyeSBmbGV4aWJsZSwgeW91IGNhbiBoYXZlIG11bHRpcGxlIGhhbmRs
ZXJzIGFuZCBjYW5jZWwgb25seSBzb21lIG9mIHRoZW0sIGluY2x1ZGUgc29tZSBub24tb3B0aW9u
YWwgY29kZSBpbiB0aGUgZGVmZXIgYmxvY2sgaXRzZWxmLCBldGMuPGJyPg==" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Sat, 7 Jan 2017 at 18:45 Charles Srstka via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">&gt; On Jan 7, 2017, at 12:40 PM, D. Felipe Torres via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Any cancelable defer addition we could come up with will need a flag/state to indicate so, which won&#39;t be that much different from what you wrote.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Having said that, for your example may I suggest this approach instead:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; func openFile(kind: String) -&gt; UnsafeMutablePointer&lt;FILE&gt;? {<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;     var file = fopen(&quot;MyFile.txt&quot;, &quot;r&quot;)<br class="gmail_msg">
&gt;     guard  fileIsValid(file)<br class="gmail_msg">
&gt;         &amp;&amp; fileContainsData(file, kind)<br class="gmail_msg">
&gt;         &amp;&amp; !fileDataOutOfDate(file) else {<br class="gmail_msg">
&gt;         fclose(file)<br class="gmail_msg">
&gt;     }<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;     return file<br class="gmail_msg">
&gt; }<br class="gmail_msg">
<br class="gmail_msg">
Or:<br class="gmail_msg">
<br class="gmail_msg">
func openFile(kind: String) -&gt; UnsafeMutablePointer&lt;FILE&gt;? {<br class="gmail_msg">
    var file = fopen(&quot;MyFile.txt&quot;, &quot;r”)<br class="gmail_msg">
<br class="gmail_msg">
    do {<br class="gmail_msg">
        if fileIsNotValid(file) { throw MyError.fileIsNotValid }<br class="gmail_msg">
<br class="gmail_msg">
        if fileDoesNotContainsData(file, kind) { throw MyError.doesNotContainData }<br class="gmail_msg">
<br class="gmail_msg">
        if fileDataOutOfDate(file) { throw MyError.dataOutOfDate }<br class="gmail_msg">
<br class="gmail_msg">
        return file<br class="gmail_msg">
    } catch {<br class="gmail_msg">
        fclose(file)<br class="gmail_msg">
    }<br class="gmail_msg">
}<br class="gmail_msg">
<br class="gmail_msg">
Charles<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>