xx-li
(Stellar)
1
protocol Merger {
associatedtype Element
func merge(_ a:Element, _ b:Element) -> Element
}
class AbstractTest<M:Merger, E> {
typealias Element = E
var a, b:E
var merger:M
init(merger:M, a:E, b:E) {
self.merger = merger
self.a = a
self.b = b
}
func test() -> E {
return self.merger.merge(a, b)
}
}
error: Cannot invoke 'merge' with an argument list of type '(E, E)'
I expect to abstract a Merger protocol for external calls. How do I use swift to implement it?
ahti
(Lukas Stabe 🙃)
2
The typealias Element = E creates a new typealias on the class AbstractTest, which does not influence the associated types of M. Instead, you should add a generic where clause to require M.Element == E.
1 Like
Nevin
3
Did you mean something like this?
class AbstractTest<M:Merger> {
var a, b: M.Element
var merger: M
init(merger: M, a: M.Element, b: M.Element) {
self.merger = merger
self.a = a
self.b = b
}
func test() -> M.Element {
return merger.merge(a, b)
}
}
1 Like
xx-li
(Stellar)
4
I want to implement a segment tree, your method solves this problem, tks.
class SegmentTree<M:Merger>: NSObject {
var merger:M
var tree:Array<M.Element>
private var data: Array<M.Element>
init(arr: Array<M.Element>, merger:M) {
self.merger = merger
self.data = Array.init(arr)
self.tree = Array.init()
super.init()
self.buildSegmentTree(treeIndex: 0, l: 0, r: self.data.count - 1)
}
func buildSegmentTree(treeIndex:Int, l:Int, r:Int) {
if l == r {
tree[treeIndex] = data[l]
return;
}
let leftIndex = leftChild(treeIndex)
let rightIndex = rightChild(treeIndex)
let mid = l + (r - l) / 2
//left = [l..mid] right = [mid+1 .. r]
buildSegmentTree(treeIndex: leftIndex, l: l, r: mid)
buildSegmentTree(treeIndex: rightIndex, l: mid + 1, r: r)
tree[treeIndex] = merger.merge(tree[leftIndex] , tree[rightIndex])
}
}
xx-li
(Stellar)
5
class AbstractTest<M:Merger, E> where M.Element == E {}
Your method can solve this problem, tks~