2017-12-18 6 views
0

In Swift, gibt es eine Möglichkeit, einen Typ von "Sets einer bestimmten Größe?" (Trotz der Abwesenheit von abhängigen Typen in Swift, ist eine solche Konstruktion dennoch möglich ohne übermäßiges „Verdrehungen?“)Sets einer bestimmten Größe als Swift-Typ

Als Beispiel würde Ich mag einen parametrisierte Typen definieren können, der Instanzen SetOfSizeTwo<T> sind Sätze, bestehend aus genau zwei Objekten (Hashable) Typ T.

Derzeit verwende ich ein armer Proxy des Mannes:

struct SetOfSizeTwo<T> where T: Hashable { 
    var set = Set<T>(minimumCapacity: 2) 
} 

Allerdings ist diese Art die Eigenschaft nicht zwingen set von 2.

aktualisieren

Die Größe zu sein Blog-Artikel A hack for fixed-size arrays in Swift, von Ole Begemann, lässt mich glauben, dass eine robuste Konstruktion eines Fixed-Size-Set-Typs in Swift 4, wenn überhaupt möglich, nicht trivial ist.

+3

Ich denke, Ihre beste Wette eine Wrapper-Klasse zu erstellen, ist mit Benutzerdefinierte Methoden zum Hinzufügen und Entfernen Und haben Sie die zugrunde liegende Datenstruktur privat, damit niemand damit basteln kann. – Michal

+0

@Michal Danke für Ihren praktischen Vorschlag. Im Grunde möchte ich die Set-Größe als Kompilierzeitbeschränkung erzwingen, idealerweise mit einem Typ. Aber ich vermute, dass das ohne Sprachunterstützung für abhängige Typen unmöglich ist. – egnha

Antwort

1

Hier ist ein Ansatz, der so nah wie möglich an Ihre Bedürfnisse angepasst ist. Es ist ein wenig rau an den Rändern und einige Polieren braucht, aber ich denke, Sie bekommen die Idee werden:

class Size { 
    let size: Int 

    init(size: Int) { 
     self.size = size 
    } 

    required init() { 
     self.size = 0 
    } 
} 

class SizeOne: Size { 
    private override init(size: Int) { 
     super.init(size: size) 
    } 

    required init() { 
     super.init(size: 1) 
    } 
} 

class SizedSet<S, T> where S: Size, T: Hashable { 
    private var set: Set<T> 
    private let maximumSize: S 

    init() { 
     set = Set<T>() 
     maximumSize = S() 
    } 

    func insert(item: T) { 
     if !set.contains(item) && set.count + 1 <= maximumSize.size { 
      set.insert(item) 
     } 
    } 

    func remove(item: T) { 
     set.remove(item) 
    } 

    func contents() -> Set<T> { 
     return set 
    } 
} 

Verbrauch:

let set: SizedSet<SizeOne, Int> = SizedSet() 
print(set.contents()) 
// [] 

set.insert(item: 1) 
print(set.contents()) 
// [1] 

set.insert(item: 2) 
print(set.contents()) 
// [1] 
Verwandte Themen