2017-05-25 49 views
1

我遇到了一個Vertex結構的設計問題。我希望能夠創建「數組」或「設置」,所以我的「頂點」不必都是相同的類型。兩種情況都給出了不同的錯誤。檢查下面的代碼。如何製作一個通用頂點,以便我可以創建具有混合類型的圖形(集合)?

預先感謝您

import Foundation 

public struct Vertex<T: Equatable> where T: Equatable, T: Hashable { 

    public var data: T 
    public let index: Int? 

    init(data: T , index: Int) { 
     self.data = data 
     self.index = index 
     } 

} 

extension Vertex: CustomStringConvertible { 

    public var description: String { 
     return "\(index): \(data)" 
    } 

} 

struct Coordinate { 
    var x : Int 
    var y : Int 

    init(x : Int, y: Int) { 
     self.x = x 
     self.y = y 
    } 

} 
extension Coordinate: Equatable {} 

func ==(lhs: Coordinate, rhs: Coordinate) -> Bool { 
    guard lhs.x == rhs.x else { 
     return false 
    } 

    guard lhs.y == rhs.y else { 
     return false 
    } 
    return true 
} 

extension Coordinate: Hashable { 
    var hashValue: Int { 
     return "\(x)\(y)".hashValue 
    } 
} 




let coord1 = Coordinate(x : 5, y: 5) 
let stringVertex1 = Vertex(data: "Hello World", index: 3) 
let stringVertex2 = Vertex(data: "Foo ", index: 3) 
let intVertex1 = Vertex(data: 2, index: 1) 
let coordVertex1 = Vertex(data: coord1, index: 1) 


//Error: Cannot convert value of type 'Vertex<String>' to expected element type 'Vertex'. 
//Even if I make myArr1 equal to [stringVertex1, stringVertex1], I still get the same error. 
let myArr1 : Array<Vertex> = [stringVertex1, intVertex1] 

//This works since the data inside "Vertex" is the same type. 
let myArr2 : Array<Vertex<String>> = [stringVertex1, stringVertex2] 

//Error: Type "Vertex" does not conform to protocol "Hashable". 
let mySet1 : Set<Vertex> = [stringVertex1, stringVertex2] 
+2

而不是試圖推出自己的圖形架構,你可能想使用已經測試並具有通用頂點支持一個:https://github.com/davecom/SwiftGraph 我是作者,雖然,所以我有點偏袒。 – davecom

+0

對於第一個錯誤,您需要爲Coordinate實現'Hashable'協議。對於第二個錯誤,您需要一個類型橡皮擦,即「AnyEraser」,它可以擦除特定類型的頂點並將其視爲任何其他類型的視圖。https://www.natashatherobot.com/swift-type-erasure/ – Alexander

+0

@穆罕默德絕對沒有任何意義。 – Alexander

回答

0

我得到了我的答案。這是最終的頂點代碼。 POP的力量!

public enum TypeOfVertex : String { 
    case Int = "Mirror for Int" 
    case Float = "Mirror for Float" 
    case Double = "Mirror for Double" 
    case Coordinates = "Mirror for Coordinate" 
    case String = "Mirror for String" 

} 


protocol AnyVertexable { 
    var type: TypeOfVertex { get set } 
    var index: Int { get set } 

} 


struct Vertex<Element : Hashable> : AnyVertexable where Element: Equatable & Hashable { 

    var type : TypeOfVertex 
    var index: Int 
    var data : Element? 

    init(index: Int, data: Element) { 
     self.data = data 
     self.index = index 
     if let type = TypeOfVertex(rawValue: data.hashValue.customMirror.description) { 
      self.type = type 
     } else { 
      fatalError() 
     } 
    } 

} 

let sample1 = Vertex(index: 0, data: 1.0) 
let sample2 = Vertex(index: 2, data: 1) 
let sample3 = Vertex(index: 3, data: Coordinate(x: 5, y: 5)) 

let myArr : [AnyVertexable] = [sample1, sample2, sample3] 
相關問題