2017-05-25 1 views
1

J'ai des problèmes avec la conception d'une structure Vertex. Je veux être capable de créer "Array" ou "Set" pour que mon "Vertex" ne soit pas nécessairement du même type. Les deux situations donnent des erreurs différentes. Vérifiez le code ci-dessous.Comment faire un Vertex générique pour pouvoir créer des Graphiques (Collections) avec des types mixtes?

Nous vous remercions à l'avance

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

Au lieu d'essayer de rouler votre propre cadre de graphique, vous pouvez utiliser celui qui est déjà testé et a un support pour les sommets génériques: https://github.com/davecom/SwiftGraph Je suis l'auteur bien , donc je suis un peu partial. – davecom

+0

Pour la première erreur, vous devez implémenter le protocole 'Hashable' pour' Coordinate'. Pour la deuxième erreur, vous aurez besoin d'un type effaceur, 'AnyEraser' qui efface le type particulier de vertex et permet qu'il soit traité comme un autre https://www.natashatherobot.com/swift-type-erasure/ – Alexander

+0

@ Muhammad Absolument pas de cela avait un sens. – Alexander

Répondre

0

J'ai eu ma réponse. C'est le dernier code de vertex. LE POUVOIR DE 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]