How do I express a Swift generic function which constraints that T
be an Optional<Equatable>
?
I've tried things like the following, with the resulting errors.
func gen<T>(arg: T) where T : Optional<Equatable>
func gen<T>(arg: T) where T : OptionalProtocol<Equatable>
func gen<T, U>(arg: T) where T : Optional<U>, U : Equatable
Thanks.
I was doing something like
if let a = arg, let b = argb
return a==b
It turns out that my error wasn't in the templating at all, it was just that the object I was working with wasn't, in fact, Equatable. I guess I assumed Swift would generate == for a struct with elements that are all themselves =='able, but it does not. Next time I'll know what the error Expression type 'Bool' is ambiguous without more context
is suggesting.
This should work:
func gen<T>(arg: T?) where T : Equatable { /*...*/ }
Which is equivalent to this:
func gen<T>(arg: Optional<T>) where T : Equatable { /*...*/ }
Remember,
Generics are for the variable part of your type requirements. That you require Optional
is constant; it's the optional-what part that's variable. So put the optionality in the actual func declaration, and leave the optional-what for generics.
The colon in type parameters expresses a subtype relationship. A type T
can't be a subtype of Optional<Something>
because Optional
is an enum — only classes and protocols can have subtypes (subclasses and conforming types respectively). Likewise, generics aren't covariant, so Optional<Foo>
where Foo
adopts Equatable
isn't a subtype of Optional<T: Equatable>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With