[swift-users] How do generics interact with overloaded methods?

David Turnbull dturnbull at gmail.com
Thu Jan 14 03:24:39 CST 2016


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.

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...

func read<T:UnsignedIntegerType>() -> T { return 1 }

func read<T:SignedIntegerType>() -> T { return -1 }

let x:Int64 = read()

let y:UInt8 = read()

Protocols are essential to generics. Figure out how they work together and
you're good to go.

-david



On Wed, Jan 13, 2016 at 11:04 PM, Ryan Conway via swift-users <
swift-users at swift.org> wrote:

> Hey swift-users,
>
> 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.
>
> 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.
>
> class Bar {
>     func read() -> Int {
>         return -1
>     }
>     func read() -> UInt {
>         return 1
>     }
>     func read<T>() -> T {
>         print("Unsupported data type requested")
>         exit(1)
>     }
> }
>
>
> Objects of that class return the requested type as expected when used like
> so:
>
> let thisWorks: Int = Bar().read() // returns -1
> let thisAlsoWorks: UInt = Bar().read() // returns 1
>
>
> 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:
>
> class Baz<T> {
>     let myBar = Bar()
>
>     func read() -> T {
>         return self.myBar.read()
>     }
> }
>
>
> Both of these invocations call the generic read<T>() -> T method rather
> than the read() -> UInt method:
>
> let thisDoesntWork = Baz<UInt>().read()
> let thisDoesntWorkEither: UInt = Baz<UInt>().read()
>
>
> 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.
>
> Thank you,
> Ryan
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160114/45c2dec4/attachment.html>


More information about the swift-users mailing list