如何将accociatedtype约束为协议

时间:2017-05-07 09:38:34

标签: swift generics protocols

如何将accociatedtype约束为协议。

假设我有以下协议和实现它的类:

public protocol TestProtocol {
    associatedtype TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<T>(_ identifier: String) throws -> T? {
        return "Test" as? T
    }
}

现在一切都很好。 func get将编译,因为在这种情况下编译器知道我的关联类型是协议。

问题始于这个用例:

public protocol TestProtocol {
    associatedtype TestType

    func get<T>(_ identifier: String) throws -> T? where T : TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<T>(_ identifier: String) throws -> T? {
        return "Test" as? T
    }
}

这不会编译,因为编译器在这种情况下不知道TestType是否是ProtocolType。

(它说:&#34;键入&#39; T&#39;限制为非协议类型&#39; TestType&#39;&#34;)

如何强制执行相关类型&#39; TestType&#39;在协议中作为协议类型?

编辑:我的第一个例子有点误导我想要实现的目标的更好定义是以下

public protocol TestProtocol {
    associatedtype TestType

    func get<T>(_ identifier: String) throws -> U? where U : TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<U>(_ identifier: String) throws -> U? where U : T{
        return "Test" as? U
    }
}

我想要返回类型&#39; get&#39;是U类型并实现协议T(我想用它来从我的持久性存储中检索数据)。

问题在于,这种表示法并未强制执行T是协议类型(这会导致编译器错误)。我怎么能强制执行呢?

第二次修改:

我看问题的时间越长,我就越能避免Swift-Proposal SE-0142解决这个问题(以及一个快速的4功能)。

https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md

但如果你有其他想法如何实现所需的行为,请告诉我;)

1 个答案:

答案 0 :(得分:0)

正如sbarow所说:

public protocol TestProtocol {

    associatedtype TestType:Protocol

    func get<TestType>(_ identifier: String) throws -> TestType? 
}