How to check/predicate function type in Swift?

为君一笑 提交于 2019-12-05 21:46:08

There's a workaround using generics:

func intF(x: Int) -> Int {
    return x
}

func stringF(x: Int) -> String {
    return "\(x)"
}

func h<T>(f: (Int) -> T) {
    if (T.self == Int.self) {
        print(f(1))
    } else {
        print("invalid")
    }
}

h(f: intF)    // prints: 1
h(f: stringF) // prints: invalid

Using Any is almost always a sign of code smell, you should try to rely as much as possible of the type safety that Swift provides. You can achieve this by making h generic, thus verifiable at compile time.

// the overload that does the actual stuff
func h(f: @escaping (Int) -> Int) {
    print(f(1))
}

// this maps to all other types
func h<T>(f: @escaping (Int) -> T) {
    print("invalid")
}

h { _ in return "15" }  // Invalid
h {  2 * $0 }           // 2

Heck, you could even give up the generic overload, thus you'll have for free compile checks instead of runtime failures (much, much reliable and predictive)

You can rewrite h into a generic function:

func h<T>(f: @escaping (Int) -> T) {        
    if T.self == Int.self  {
        print(f(1))
    } else {
        print("invalid")
    }
}

But the better way to to write type-specific overloads for h and a generic catch-all for the rest (if you need it at all).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!