2017-07-15 113 views
1

如何创建通用协议,该通用协议具有另一种通用协议的类型?具有通用协议类型变量的通用协议

在我的例子中,我有一个堆,它是泛型类型的协议,因为我的堆中可以有任何符合Comparable协议的元素。

所以在我的priorityQueue中,我也希望作为一个协议(为了避免代码重复和实践)我希望我的priorityQueue包含一个堆,其中Heap.T等于PriorityQueue.Item,但我不知道该怎么做。有任何想法吗?

当然,我可以用“抽象类”来实现,但这不是重点。

BTW甚至低于代码不编译

代码:

public protocol PriorityQueuable: Hashable { 
    associatedtype KeyType: Comparable 
    associatedtype ValueType: Comparable 

    var key: KeyType { get set } 
    var value: ValueType { get set } 
} 

protocol Heap { 
    associatedtype T: Comparable 

    var data: [T] { get set } 

    mutating func heapify(parentIndex: Int) 
} 

protocol PriorityQueue { 
    associatedtype Item: PriorityQueuable 

    //FIXME: doesn't allow me to do that. Why? 
    var heap: Heap<Item> { get set } 

    // doesn't compile as well 
    // var heap: Heap { get set } 
} 
+0

如果你做'PriorityQueue'的'Heap' – Lawliet

+0

自从斯威夫特的数据结构多的Structs一个子类? ,我想将一个优先级队列的具体实现作为一个结构体,但由于结构体不允许继承,所以我决定不考虑这个选项。 +这是一个学习语言的新机会 – denis631

+0

尝试包装'堆'与通用类 – paper1111

回答

1

此代码:

public protocol PriorityQueuable: Hashable { 
    associatedtype KeyType: Comparable 
    associatedtype ValueType: Comparable 

    var key: KeyType { get set } 
    var value: ValueType { get set } 
} 

protocol Heap { 
    associatedtype T: Comparable 

    var data: [T] { get set } 

    mutating func heapify(parentIndex: Int) 
} 

class AnyHeap<U: Comparable>: Heap { 
    public init(data: [U], heapify: @escaping (_ parentIndex: Int) ->()) { 
     self.data = data 
     self.anyHeapify = heapify 
    } 

    var anyHeapify: (_ parentIndex: Int) ->() 
    var data: [U] 
    func heapify(parentIndex: Int) { 
     self.anyHeapify(parentIndex) 
    } 
} 

protocol PriorityQueue { 
    associatedtype Item: PriorityQueuable, Comparable 

    var heap: AnyHeap<Item> { get set } 
} 

注意,有一个额外的AnyHeap类符合HeapAnyHeap a Heap由于多态性。 (注意:Item必须符合Comparable符合协议Heap)实施这些协议是非常容易的:

class AQueueable: PriorityQueuable, Comparable { 
    var hashValue: Int { return 1 } 
    var key: String = "Hi" 
    var value: String = "YoMaMa" 
    static func < (lhs: AQueueable, rhs: AQueueable) -> Bool { 
     // implement code 
     return false 
    } 
    static func == (lhs: AQueueable, rhs: AQueueable) -> Bool { 
     // implement code 
     return false 
    } 
} 

class AQueue: PriorityQueue { 
    var heap: AnyHeap = AnyHeap<AQueueable>(data: [AQueueable](), heapify: { parentIndex in 
     // implement code 
    }) 
} 
+0

谢谢,但那正是我试图避免的事情,即创建一个通用类。我只想使用通用协议来解决它。似乎,斯威夫特现在不允许它 – denis631

+0

因为即使苹果有AnyDictionaries和AnyArrays ...虽然不是很灵活和美丽... – denis631