Swift泛型类型选择不会传播

时间:2015-11-11 15:22:01

标签: swift generics types

如果我理解正确,Swift可以通过不同的方式确定泛型的实际类型,包括按返回类型匹配。相同(或类似)机制用于消除重载函数的歧义。所以这可以按预期工作:

func getValue<T>()->T? {
    return nil
}

func getValue()->Int? {
    return 13
}

let b: Int? = getValue()

运行此功能时,b将为13。从技术上讲,两个函数签名都是合适的,但后者更适用于请求的返回类型。

让我们添加第二个函数并通过它来隧道调用:

func getGetValue<T>()->T? {
    return getValue()
}

let c: Int? = getGetValue()

运行此功能时,c将为nil。实际上,编译器将选择从getGetValue()调用的泛型getValue()实现,这不是我想要的。恕我直言,在getValue()的两个实现之间进行选择时,请求的返回类型应该通过第二个泛型传播,从而产生与第一个示例中相同的行为。

我错过了什么? (Xcode 7.1)

2 个答案:

答案 0 :(得分:0)

我尝试明确传播通用类型,但它仍然无法正常工作(所以你这是一个问题):

func getGetValue<T>()->T? {
    guard let value: T? = getGetValue()
    return value
}

这是一种稍微不同的方法,但是可能会使用协议获得您正在寻找的内容(使用协议可以保留某些类型信息)

// Protocol for getting a value
protocol GetValue {
    static func getValue() -> Self?
}

// Default implementation
extension GetValue {
    static func getValue() -> Self? {
        return nil
    }
}

// Int implementation
extension Int: GetValue {
    static func getValue() -> Int? {
        return 13
    }
}

// Our generic getGetValue function for any type that implements GetValue
func getGetValue<T: GetValue>()->T? {
    return T.getValue()
}

let a: Int? = getGetValue() // 13

// Making String implement the protocol (It gets the default implementation)
extension String: GetValue {

}

let b: String? = getGetValue() // nil

答案 1 :(得分:0)

你只是忘记投射了。

func getValue<T>()->T? {
    return nil
}

func getValue()->Int? {
    return 13
}

let b: Int? = getValue() // 13

func getGetValue<T>()->T? {
    return getValue() as? T
}

let c: Int? = getGetValue() // 13