关联类型的值可以是协议吗?

时间:2018-04-12 09:53:24

标签: swift generics swift-protocols

关联类型的值可以是协议吗?

protocol A {
    var name: String {get set}
}

protocol B: A {}

protocol C {
    associatedtype T: B
    var t : T {get set}
}

class D : C {
    var t : B

    init(t : B) {
        self.t = t
    }
}

class E : B {
    var name: String = ""
}

class F : B {
    var name: String = "ff"
}    

在D类中,如果t的类型是E或F,则代码编译。但是如果t的类型是B(这是一个协议),则编译失败说明:

  

键入' D'不符合协议' C'

如何使用关联类型来保存协议值?任何关于它失败原因的指示?

更新了问题

删除关联类型的绑定并且只有T将无济于事。我的协议也有我想要访问的方法。例如:

protocol A {
    func sayHello()
}

protocol B : A  {
    var name: String {get set}
}

extension B {
    func sayHello() {
        print("Hello")
    }
}

protocol C {
    associatedtype T
    var t: T {get set}
}

class D : C {
    typealias T = E
    var t: T

    init(t : T) {
        self.t = t
    }
}

class E : B {
    var name: String = ""
}

class F : B {
    var name: String = "ff"
}

class G<S: C> {
    var a: S

    init(a: S) {
        self.a = a
    }

    func notWorking() {
        a.t.sayHello()
    }
}

在上面的示例中,我无法访问sayHello方法。

1 个答案:

答案 0 :(得分:1)

Generic Protocols with Associated Type

protocol C {
    associatedtype T
    var t : T {get set}
}

符合C的任何内容都必须实现associatedtype T。但是,类型未定义。因此,符合协议的类或结构必须隐式或显式地定义它。

首先,让我们创建一个符合C的类SomeClass。我们必须定义t。好吧,您可以根据与t相关联的值定义T

class D : C {

    typealias T = B
    var t: B

    init(t : B) {
        self.t = t
    }
}

<强>更新

您已创建T associatedtype,表示分配动态泛型类型值,在这种情况下,已分配T值。为什么要创建关联类型,可以直接使用。像

protocol C {
    //associatedtype T: B 
    //var t : T {get set}

    var t: B {get set} // write directly.
}