2014-09-22 6 views
7

ich kämpfen, um zu verstehen, warum es zwei verschiedene Strukturen in Swift sind die fast gleich sind.SequenceOf und LazySequence - was ist der Unterschied und Gebrauch bestimmt?

  • Ist SequenceOf nicht faul?
  • Was die Verwendungszwecke für jeden sind?

Edit: Ich denke, ich verstehe immer noch nicht, was "faul" in der Folge bedeutet ... F.E. diesen Code nehmen, die SequenceOf verwendet, das ist angeblich nicht faul:

func myMap<S: SequenceType, V>(source: S, 
     selector: S.Generator.Element -> V) -> SequenceOf<V> { 
     let seq = SequenceOf { 
     _ -> GeneratorOf<V> in 
     var gen = source.generate() 
     return GeneratorOf { 
      let v = gen.next() 
      println(v) 
      return v == nil ? nil : selector(v!) 
     } 
     } 
     return seq 
    } 

ist es mit

let a = myMap([1, 2, 3], { $0 * 2 }) 
    var gen = a.generate() 
    let v1 = gen.next() 
    let v2 = gen.next() 

Optional (1)

Optional (2)

nennen Lassen Sie druckt

mir Sieht faul ...

Edit # 2:

Wenn Karte über eine faule Sequenz scheint es trotzdem eifrig Elemente zu evaluieren:

struct TransientView<S: SequenceType> : SequenceType { 

    private let seq: S 

    init(_ seq: S) { 
     self.seq = seq 
    } 

    func generate() 
     -> GeneratorOf<S.Generator.Element> { 
      var g = seq.generate() 
      return GeneratorOf { 
       println("next") 
       return g.next() 
      } 
    } 
} 

let seq = lazy(map(TransientView([1, 2, 3]), { $0 * 2 })) 

druckt "next" 4 mal ...

Edit # 3. Hier ist meine aktuelle Meinung: Es wäre falsch zu sagen "SequenceOf ist nicht faul". Es ist eher "SequenceOf wird mit nicht-faulen .map, .filter, etc erweitert". Es ist durchaus möglich, faule Versionen von Map, Filer usw. zu schreiben, die für jede Sequenz gelten würden, einschließlich SequenceOf. Aber hat Apple entschieden, das „faule“ Paradigma nicht nur auf Fälle von Sequenzen anwenden, sondern Elemente als auch zu sequenzieren - wenn Sie also Sequenzvariable als faul deklarieren, wird LazySequence verwendet und als solche Erweiterungen sind faul. Ich denke, das ist ein falscher Ansatz und eine faule Deklaration sollte nicht auf Elemente übertragen werden - stattdessen sollten Elemente so lange wie möglich faul gehalten werden. Es ist einfach, faul in eifrig zu konvertieren, aber sonst nicht möglich.

Antwort

12

Ist SequenceOf nicht faul?

Richtig. Es ist nicht faul. Deshalb existieren die faulen Formen.

Was sind die vorgesehenen Verwendungen?

Airpseed Velocity hat wahrscheinlich die umfassendste Diskussion der verschiedenen Arten. SequenceOf bietet einfache Möglichkeiten zum Generieren von Sequenzen aus einer Schließung. Es bietet auch eine Art "Sequenztypumwandlung", um einen Sequenztyp in einen anderen zu konvertieren.

LazySequence wird in erster Linie mit der lazy-Funktion erstellt. Airspeed Velocity Working at being lazy gibt ein nettes Intro. Sein Zweck besteht darin, die Erzeugung von Elementen zu vermeiden, bevor sie tatsächlich benötigt werden, was besonders nützlich für unendliche Sequenzen ist, aber in jedem Fall nützlich ist, wenn Sie nicht alle Elemente benötigen und sie nicht einfach zu erzeugen sind.

Habe ich erwähnt, dass Sie Airspeed Velocity lesen sollten, wenn Sie Deep-Dives auf diesem Zeug wollen? Aber es ist immer noch wichtig zu wissen, dass wir nur das haben, was wir aus den Kopfzeilen ableiten können, aus Devforum-Diskussionen und aus dem, was wir sonst über Swift wissen. Die untergeordneten Typen sind noch nicht gut dokumentiert und gehören nicht zu den "offiziellen" Dokumenten, und sie haben sich mehrmals gegenüber den Betaversionen geändert. Es ist also nicht immer einfach zu wissen, was das Swift-Team für sie in zukünftigen Versionen vorhat. Das ist das Beste, was wir bisher wissen.


EDIT: Wie ich in den Kommentaren beachten Sie, gibt es keine map Funktion, die eine LazySequence in 6.1b3 nimmt und zurückgibt. Es gibt nur eine map Methode auf LazySequence. Aber wir können einen bauen, wenn wir wollen, und vielleicht fügen sie ihn schließlich hinzu:

func map<S: SequenceType, U>(source: LazySequence<S>, transform: S.Generator.Element -> U) -> LazySequence<MapSequenceView<S, U>> { 
    return source.map(transform) 
} 
+1

Danke, Airspeed Velocity ist mein bester Freund jetzt! –

+0

Können Sie Sequenz Faulheit erklären? - immer noch nicht verstanden ... Aktualisiert die Frage. –

+0

Wenn Sie 'map' auf eine Lazy-Sequenz anwenden, wird ein neuer Generator zurückgegeben, ohne dass alle Werte berechnet werden. Wenn Sie 'map' auf eine nicht-verzögerte Sequenz anwenden, berechnet sie alle Werte sofort und gibt ein Array zurück. –

Verwandte Themen