I need to declare two protocols, they both have 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?)
}
With this current protocol definition, the associatedtype DataType
of MyView
is not really the same as the one in MyLayout
:
extension MyView {
func doLayout() {
layout.computeLayout(with: self.data)
^^^^^^^^^
Cannot convert value of type 'Self.DataType' to expected argument type '_?'
}
}
The compiler is telling us that the type is not the same.
Is there a way to share an associatedtype between two protocols to fix my issue? Thanks.
The problem is that it's possible for an implementation of MyView
to have a LayoutType
with a different DataType
to its own DataType
. Once SE-0142: Permit where clauses to constrain associated types is implemented, you'll just be able to say:
associatedtype LayoutType : MyLayout where LayoutType.DataType == DataType
in order to enforce that conforming types must have a LayoutType
with a matching DataType
.
However, until this happens, the best you're probably going to be able to do is add the constraint to the extension – which will only make the default implementation of doLayout()
available if the DataType
s match.
extension MyView where LayoutType.DataType == DataType {
func doLayout() {
layout.computeLayout(with: data)
}
}