Search code examples
swiftgenericsprotocols

Can you Strict Generic types or give one parameter more than one type ?


For example i want to specify a type that might be Integer or String and use it as special type in func i tried typealias but it wont solve the case because typealiases can't have or arguments as its only uses & therefore consider the case below.

typealias alis = StringProtocol & Numeric


func foo <T: alis> (vee: T) -> T{
// do something
    return vee
}

i want this func to accept a parameter type of either ( Int or String ) not anything else (<T>),

as you can see i tried with typealias and i have no compile error.

however trying to use the function will lead to these errors.

foo(vee: 1) //Argument type 'Int' does not conform to expected type 'StringProtocol'

And

foo(vee: "v") //Argument type 'String' does not conform to expected type 'Numeric'

is this achievable with swift ? if so how.


Solution

  • Let's suppose that you could use a OR operator to combine protocols, what would you be able to do with something of type (Int | String)?

    Not everything you can do to an Int can be done on (Int | String), because it might be a string underlyingly. Similarly, not everything you can do to an String can be done on (Int | String), because it might be a Int underlyingly.

    Now you might say "Ah. I know that Int and String both have a description property. I should be able to access description on a variable of type (Int | String)."

    Well, in that case, you can just create such a protocol yourself and only have Int and String conform to it:

    protocol IntOrString {
        var description: String { get }
    }
    
    extension Int : IntOrString {}
    extension String : IntOrString {}
    

    (Note that description is already defined in CustomStringConvertible. For the sake of argument, imagine that does not exist.)