<div dir="ltr"><div>You're using generics like they were templates. A lot of people coming from C++ will make this mistake at first. Here's the secret: C++ templates are a substitution at compile time. Swift generics have to satisfy the protocols.<br></div><div><br></div><div>Your example is contrived to show exactly how templates work and generics don't work. It's not fixable. But here's some code to ponder that will lead you down the right path...</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">func</span> read<T:<span style="color:rgb(112,61,170)">UnsignedIntegerType</span>>() -> <span style="color:rgb(112,61,170)">T</span> { <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(39,42,216)">1</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">func</span> read<T:<span style="color:rgb(112,61,170)">SignedIntegerType</span>>() -> <span style="color:rgb(112,61,170)">T</span> { <span style="color:rgb(187,44,162)">return</span> -<span style="color:rgb(39,42,216)">1</span> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">let</span> x:<span style="color:rgb(112,61,170)">Int64</span> = <span style="color:rgb(49,89,93)">read</span>()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">let</span> y:<span style="color:rgb(112,61,170)">UInt8</span> = <span style="color:rgb(49,89,93)">read</span>()</p></div><div><br></div><div>Protocols are essential to generics. Figure out how they work together and you're good to go.</div><div><br></div><div>-david</div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 13, 2016 at 11:04 PM, Ryan Conway 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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><span style="font-size:12.8px">Hey swift-users,</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I'm teaching myself Swift, coming from a mostly C and Python background, and would like to understand generics more deeply. Right now, I'm seeing generic data types invoke overloaded methods in ways I do not understand, and am seeking clarification why.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">In an effort to model a data structure whose data can be represented as multiple data types simultaneously, I've made this class. Here its implementation is mocked using constants.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div>class Bar {</div><div> func read() -> Int {</div><div> return -1</div><div> }</div><div> func read() -> UInt {</div><div> return 1</div><div> }</div><div> func read<T>() -> T {</div><div> print("Unsupported data type requested")</div><div> exit(1)</div><div> }</div><div>}</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Objects of that class return the requested type as expected when used like so:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div>let thisWorks: Int = Bar().read() // returns -1</div><div>let thisAlsoWorks: UInt = Bar().read() // returns 1<br></div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">However, when I introduce generics on top of that class, the expected method (the "most precise" method) is not called. For example, given this other class:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div>class Baz<T> {</div><div> let myBar = Bar()</div><div> </div><div> func read() -> T {</div><div> return self.myBar.read()</div><div> }</div><div>}</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Both of these invocations call the generic read<T>() -> T method rather than the read() -> UInt method:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div>let thisDoesntWork = Baz<UInt>().read()</div><div>let thisDoesntWorkEither: UInt = Baz<UInt>().read()</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Am I using generics wrong here? Is there some other language feature I should be using to capture this data? Any pointers would be greatly appreciated.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Thank you,</div><div style="font-size:12.8px">Ryan</div></div>
<img alt="" width="1" height="1" border="0" style="min-height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;">
<br>_______________________________________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org" target="_blank">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></div>