2017-07-15 153 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