Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Generic func gen<T>(arg: T) where T : Optional<U>, U : Equatable

Tags:

generics

swift

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>

  • Type 'T' constrained to non-protocol type 'Optional'

func gen<T>(arg: T) where T : OptionalProtocol<Equatable>

  • Cannot specialize non-generic type 'OptionalProtocol'

func gen<T, U>(arg: T) where T : Optional<U>, U : Equatable

  • Type 'T' constrained to non-protocol type 'Optional'
  • Generic parameter 'U' is not used in function signature

Thanks.

Edit

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.

like image 763
frankleonrose Avatar asked Feb 07 '17 00:02

frankleonrose


1 Answers

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,

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

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

like image 85
rickster Avatar answered Nov 10 '22 23:11

rickster