【问题标题】:Generics and protocol conformance in Swift functionsSwift 函数中的泛型和协议一致性
【发布时间】:2015-09-07 22:55:13
【问题描述】:

我刚刚阅读了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 实际上符合这些,所以类型系统应该没问题,你可以返回它。

但事实并非如此。为什么?

【问题讨论】:

  • 因为return T还受输入参数类型的限制,可能与Bar不兼容。

标签: swift generics protocols


【解决方案1】:

虽然Bar 确实符合ValueSmashable,但它并不是满足这些标准的唯一 类型。我可以创建一个新类型(使用最新的 Swift 语法):

struct NotBar: Smashable, Value {
    func valueBySmashing​OtherValue​<T:Value where T:Smashable>(value: T) -> T {
        return value;
    }
}
func ==(lhs: NotBar, rhs: NotBar) -> Bool {
    return true
}

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

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    相关资源
    最近更新 更多