I'm new to Swift and have been messing around with some code. I've defined a Layout class similar to the WWDC talk on protocol oriented programming. It looks like this:
protocol Layout {
associatedtype Content: AnyObject
var contents: [Content] { get }
func layout()
}
Basically, I'd like a protocol layout which knows how to lay out some type of content (NSViews, UIViews, etc).
I'd like to extend this protocol like so:
protocol StackableLayout : Layout {
var children: [Layout] { get set }
}
Where a StackableLayout is a layout that can handle an array of things of type layout. However this doesn't compile because of the associated type on Layout.
This compiles:
protocol StackableLayout : Layout {
associatedtype Child: Layout
var children: [Child] { get set }
}
But enforces that everything I'm stacking be of the same type:
struct YStackLayout<Child: Layout> : StackableLayout {
var children: [Child]
So I can't have a YStackLayout of arbitrary Layout items. How can I accomplish this?
I came across these posts which look similar but I can't figure out how to apply them: How to define a protocol with an array of a protocol with an associated type How do I add different types conforming to a protocol with an associated type to a collection?
EDIT: It seems that type-erasure is what I need here. A linked example:
struct AnyAnimal<Food>: Animal {
private let _feed: (Food) -> Void
init<Base: Animal where Food == Base.Food>(_ base: Base) {
_feed = base.feed
}
func feed(food: Food) { _feed(food) }
}