<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">A simple deinitOnNil/deinitOnError will be insufficient as soon as you have to allocate more than one resources with a failable point in between.<div class=""><br class=""></div><div class="">I think that it could best be solved with move semantics but that's far off Swift 3.<br class=""><div class=""><div class="">
<br class="Apple-interchange-newline"><span style="color: rgb(0, 0, 0); font-family: 'Lucida Grande'; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; display: inline !important; float: none;" class="">Félix</span>
</div>

<br class=""><div><blockquote type="cite" class=""><div class="">Le 26 janv. 2016 à 12:15:46, Chris Eidhof via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Now that we can return nil from a failable initializer without having initialized all the properties, it’s easier to make a mistake. For example, consider the following (artificial) code:<div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> MyArray&lt;T&gt; {</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; color: rgb(112, 61, 170);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="" class=""> pointer: </span>UnsafeMutablePointer<span style="" class="">&lt;</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span><span style="" class="">&gt;</span></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> capacity: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; min-height: 15px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>?(capacity: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) {</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">pointer</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">UnsafeMutablePointer</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">alloc</span>(capacity)</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span> capacity &gt; <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">100</span> {</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span>// Here we should also free the memory. In other words, duplicate the code from deinit.</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">capacity</span> = capacity</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; min-height: 15px;" class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; min-height: 15px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">deinit</span> {</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT'; color: rgb(79, 129, 135);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>pointer<span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">destroy</span><span style="" class="">(</span>capacity<span style="" class="">)</span></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">}</div></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">In the `return nil` case, we should really free the memory allocated by the pointer. Or in other words, we need to duplicate the behavior from the deinit.</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">Before Swift 2.2, this mistake wasn’t possible, because we knew that we could count on deinit being called, *always*. With the current behavior, return `nil` is easier, but it does come at the cost of accidentally introducing bugs. As Joe Groff pointed out, a solution would be to have something like “deferOnError” (or in this case, “deferOnNil”), but that feels a bit heavy-weight to me (and you still have to duplicate code).</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">In any case, I think it’s nice that we can now return nil earlier. I don’t like that it goes at the cost of safety, but I realize it’s probably only making things less safe in a small amount of edge cases.</div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: 'Akkurat TT';" class="">Chris</div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>