Swift协议协变特性

时间:2018-02-05 13:04:11

标签: swift generics types swift-protocols

任何人都可以解释为什么这不能编译吗?

// In MyViewKit.framework

protocol UserRenderable {
    var name : String { get }
}

protocol PostRenderable {
    var title: String { get }
    var author: UserRenderable { get }
}

// In MyDataKit.framework

struct User {
    let id: String
    let name : String
}

struct Post {
    let id: String
    let title: String
    let author: User
}

// In MyApp

extension User : UserRenderable {}

extension Post: PostRenderable {}

但这(下图)呢?显然,协议中的只读属性要求不能由符合它们的属性满足(根据this question的答案。)

typealias在这做什么?

// In MyViewKit.framework

protocol UserRenderable {
    var name : String { get }
}

protocol PostRenderable {
    var title: String { get }
    var author: UserRenderable { get }
}

// In MyDataKit.framework

struct User {
    let id: String
    let name : String
}

struct Post {
    let id: String
    let title: String
    let author: User
}

// In MyApp    

extension User : UserRenderable {}

extension Post: PostRenderable {
    // what is type alias doing here? Note: there are no associated types.
    typealias User = UserRenderable
}

更新只是澄清为什么IMO不是Why can't a get-only property requirement in a protocol be satisfied by a property which conforms?的副本。我理解Swift语言的局限性:我试图了解这是否是一个有效的解决方法。

1 个答案:

答案 0 :(得分:0)

在此特定实例中,typealias与关联类型无关。如果无法推断,Typealias只是让编译器知道协议中关联类型是什么的一种方法,但是也可以在不同的上下文中使用typealias。

您的第二个示例已编译,因为您在User扩展名中将UserRenderable从具体类型更改为Post的类型。如果您在Xcode中检查author的类型,您会看到其类型实际上是UserRenderable,而不是User。由于类型,Post内,User不会引用User结构,而是UserRenderable,因为您对类型进行了本地覆盖