Search code examples
genericsswift3extension-methods

In Swift can you constrain a generic to two types? String and Int


In Swift3, can you do this ...

 func example<T>()->(T) where T can only be String or Int

Or, do you just have to have two extensions?

For example, the function calculates a math function.

The input is conceptually a "number" but it could be either a string in French, or, an integer. So the input could be a String "cent" or an Int 100. the result would be say the square root, so either String "dix" or Int 10.


Solution

  • For this concrete case of an input is conceptually a "number" but it could be either a string in French, or, an integer, see Rickster's fantastic answer. In short, flatten all your various inputs into on cannonical form (of a single type), and work with that. In this example, that would mean parsing the French into an Int, and then only working with Int for your real computation.

    For the more general case of needing to return one out of finite set of possible types, here's my original answer:

    This is not a job for generics. There's nothing generic about working with a static set of two types.

    This the perfect situation to use an enumeration:

    enum SomeEnum { //TODO: name me
        case string(String)
        case int(Int)
    }
    
    func foo(input: SomeEnum) -> SomeEnum {
        switch input {
            case .string(let s):
                print("This is a String: \(s)")
                return(.string("abc"))
            case .int(let i):
                print("This is an Int: \(i)")
                return(.int(123))
        }
    }
    
    print(foo(input: SomeEnum.string("qwerty")))
    print(foo(input: SomeEnum.int(5)))
    

    You can try it here