2016-11-02 70 views
1

我需要声明两个协议,它们都具有associatedtypes:如何在两个协议之间共享关联类型?

protocol MyView { 
    associatedtype DataType 
    associatedtype LayoutType : MyLayout 

    var data: DataType { get } 
    var layout: LayoutType { get } 

    func doLayout() 
} 

protocol MyLayout { 
    associatedtype DataType 

    func computeLayout(with data: DataType?) 
} 

按照目前的协议定义,MyViewassociatedtype DataType是不是真的一样的一个在MyLayout

extension MyView { 
    func doLayout() { 
    layout.computeLayout(with: self.data) 
           ^^^^^^^^^ 
    Cannot convert value of type 'Self.DataType' to expected argument type '_?' 
    } 
} 

的编译器告诉我们这个类型是不一样的。

有没有办法在两种协议之间共享关联类型来解决我的问题?谢谢。

+0

也许你的意思是让来自其他2 – Alexander

+0

@AlexanderMomchliov继承的协议 - 我已经尝试过(https://gist.github.com/anonymous/58fb6e95549081ba8eff9c7fc81d6fc2),它失败,出现同样的错误。 – MartinMoizard

回答

2

问题是,MyView的实现可能有一个LayoutType,其自身的DataTypeDataType不同。一旦SE-0142: Permit where clauses to constrain associated types实现,你只能够说:

associatedtype LayoutType : MyLayout where LayoutType.DataType == DataType 

,以强制执行符合类型必须有一个相匹配DataType一个LayoutType

但是,在这种情况发生之前,您可能要做的最好的事情是将约束添加到扩展中 - 如果DataType匹配,则只会使默认实现doLayout()可用。

extension MyView where LayoutType.DataType == DataType { 
    func doLayout() { 
     layout.computeLayout(with: data) 
    } 
}