Reputation: 38475
I have a generic type
enum ResultState<T> {
case found(T)
}
with a few extensions
extension ResultState {
func hello() { print("Hello") }
}
extension ResultState where T: Collection {
func hello() { print("Hello, collection") }
}
These work perfectly and exactly as I would expect them to:
ResultState.found(1).hello() // prints "Hello"
ResultState.found([1]).hello() // prints "Hello, collection"
However, if they are called from within another generic function it doesn't behave the same
func myFunction<T>(_ state: ResultState<T>) {
state.hello()
}
For example,
myFunction(ResultState.found(1)) // prints "Hello"
myFunction(ResultState.found([1]) // prints "Hello"
Now, the basic version of hello is called each time, even though inspecting T
inside myFunction
shows it is definitely Array<Int>
.
Is this expected Swift behaviour?
If so, how would I work around it - how can I get the correct version of hello
called from within myFunction
?
Upvotes: 4
Views: 249
Reputation: 52013
It looks to me that the information is lost for myFunction and only applies one level down so to speak for ResultState. Not sure this is the solution you want but one way is to define different functions in the same way you have different extensions.
func myFunction<T: Collection>(_ state: ResultState<T>) {
state.hello()
}
func myFunction<T>(_ state: ResultState<T>) {
state.hello()
}
Executing
ResultState.found(1).hello()
ResultState.found([1]).hello()
myFunction(ResultState.found(1))
myFunction(ResultState.found([1]))
will yield
Hello
Hello, collection
Hello
Hello, collection
Upvotes: 1