-
-
Save stigi/0dec0f072119c9c8e150e8e4a954929e to your computer and use it in GitHub Desktop.
| import Foundation | |
| protocol ProtocolType { | |
| func test() -> () | |
| } | |
| struct StructOne: ProtocolType { | |
| func test() -> () {} | |
| } | |
| struct StructTwo: ProtocolType { | |
| func test() -> () {} | |
| } | |
| struct StructThree: ProtocolType { | |
| func test() -> () {} | |
| } | |
| func doSomethingGeneric<T where T:ProtocolType>(with: T) -> () { | |
| print("protocol") | |
| } | |
| func doSomethingGeneric(with: StructOne) -> () { | |
| print("struct one") | |
| } | |
| func doSomethingGeneric(with: StructTwo) -> () { | |
| print("struct two") | |
| } | |
| doSomethingGeneric(StructOne()) | |
| doSomethingGeneric(StructTwo()) | |
| doSomethingGeneric(StructThree()) | |
| let array:[ProtocolType] = [StructOne(), StructTwo(), StructThree()] | |
| array.forEach(doSomethingGeneric) // <- why does this not work? |
Declaring the generic function the following way doesn't help:
func doSomethingGeneric<T:ProtocolType where T:ProtocolType>(with: T) -> () Using array.forEach { doSomethingGeneric($0) } gives me the following error: "Cannot invoke 'doSomethingGeneric' with an argument list of type '((ProtocolType))'"
It works if you declare the function like this:
func doSomethingGeneric<T where T:ProtocolType>(with: T) -> () {
print("protocol")
}(You don't have to remove the other two definitions of the function. I don't know why you got the "ambiguous reference" error before. Probably because the compiler could not yet determine the type of the argument inside the forEach closure before it found a suitable declaration of doSomethingGeneric so it treats all matching functions as candidates.)
The reason is (I think) that ProtocolType is a different type than T where T: ProtocolType. The latter describes a single concrete type T that adopts ProtocolType. Your array is a heterogeneous collection of different types that all conform to ProtocolType. That is not the same.
There are two issues:
doSomethingGenericthe compiler errors: "Cannot convert value of type '(_) -> ()' to expected argument type '(ProtocolType) -> Void'"When I
print("\(array.dynamicType.Generator.Element.self)")it outputsProtocolTypeso I'd assume the function signature for theforEachargument to be(ProtocolType) -> ()