Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Generics - Which method is called?

Tags:

generics

swift

Assume the following toy example:

protocol AwesomeType: Equatable {
     var thingy: Int { get }
}

extension Array where Element: Equatable {

    func doThing { ... }
}

extension Array where Element: AwesomeType {

    func doThing { ... }
}

extension String: AwesomeType {

    var thingy: Int { return 42 }
}

If I have an array of Strings - [ "Foo", "Bar", "Baz" ] - and I call doThing() on it, which implementation will be called? Why?

I believe this is determined at compile time; in other words it's not a dynamic dispatch. But how is it determined? It feels like it would be similar to the rules around protocol extensions, but that's a dynamic dispatch situation...

like image 581
edelaney05 Avatar asked Feb 12 '16 21:02

edelaney05


People also ask

What is Associatedtype in Swift?

An associated type gives a placeholder name (or alias) to a type that is used as part of the protocol. The actual type to use for that associated type is not specified until the protocol is adopted. Associated types are specified with the typealias keyword.

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.


1 Answers

It yields a

error: ambiguous use of 'doThing()'

Using the simply modified example:

protocol AwesomeType: Equatable { }

extension Array where Element: Equatable {
    func doThing() { print("array one") }
}

extension Array where Element: AwesomeType {
    func doThing() { print("array two") }
}

extension String: AwesomeType { }

let arr = [ "Foo", "Bar", "Baz" ]

arr.doThing()

The compiler complains

error: ambiguous use of 'doThing()'

note: found this candidate
func doThing() { print("array one") }

note: found this candidate
func doThing() { print("array two") }

The compiler simply does not know which one to call since the two methods have identical name and parameters.

Having multiple methods named the same but not actually related always poses the risk of some compiler problems when the two eventually overlap at some point.

like image 151
luk2302 Avatar answered Sep 28 '22 13:09

luk2302