Swift函数中的泛型和协议一致性

时间:2015-06-22 13:08:14

标签: swift generics protocols

我刚刚阅读Brent Simmon's post on a problem he is having with Swift,我认为我得到了答案:通用协议一致性。

他遇到的问题是他的协议Value符合Equatable。他有另一个协议Smashable,需要函数valueBySmashingOtherValue。他有一个结构Bar,实际上符合SmashableValue

在采用泛型T的后续函数中,返回Bar。 Swift类型系统抱怨'Bar' is not convertible to 'T'

以下是我的想法:

protocol Value: Equatable { }

protocol Smashable {
    func valueBySmashing​OtherValue​<T: Value, Smashable>(value: T) -> T
}

struct Bar: Smashable, Value {
    func valueBySmashing​OtherValue​<T: Value, Smashable>(value: T) -> T {
        return value;
    }
}

func ==(lhs: Bar, rhs: Bar) -> Bool {
    return false
}

struct Foo {
    func valueBySmashing​OtherValue​<T: Value, Smashable>(value: T) -> T {
        return Bar()
    }
}

使通用类型T符合ValueSmashableBar实际上确实符合这些,所以类型系统应该没问题就可以了。

但它不是。为什么呢?

1 个答案:

答案 0 :(得分:0)

虽然Value确实符合Smashablestruct NotBar: Smashable, Value { func valueBySmashing​OtherValue​<T:Value where T:Smashable>(value: T) -> T { return value; } } func ==(lhs: NotBar, rhs: NotBar) -> Bool { return true } ,但它不是符合这些条件的唯一类型。我可以创建一个新类型(使用最新的Swift语法):

NotBar

如果我将Foo.valueBySmashing​OtherValue的实例传递给NotBar,那么我希望得到Bar作为回报。编译器知道这一点,因此它不允许您返回ngCGH