2017-12-24 16 views
0

Ich bin neu bei Swift und erkunde, was passiert, wenn eine Sammlung geändert wird, während mit einem Range darüber iteriert wird. Ich kann nicht herausfinden, warum diese beiden Schleifen unterschiedliches Verhalten haben:Ändern eines Swift-Arrays beim Iterieren über seinen Bereich - 0 zum Zählen vs. StartIndex bis EndIndex

var things = ["a", "b", "c"] 
for i in 0..<things.count { 
    print("i: \(i) count: \(things.count) value: \(things[i])") 
    if i == 1 { 
     things.append("x") 
    } 
} 
// i: 0 count: 3 value: a 
// i: 1 count: 3 value: b 
// i: 2 count: 4 value: c 

vs

var things = ["a", "b", "c"] 
for i in things.startIndex...things.endIndex { 
    print("i: \(i) count: \(things.count) value: \(things[i])") 
    if i == 1 { 
     things.append("x") 
    } 
} 
// i: 0 count: 3 value: a 
// i: 1 count: 3 value: b 
// i: 2 count: 4 value: c 
// i: 3 count: 4 value: x 

ich diese Array-Klasse Erweiterung geschaffen, so konnte ich sehen, wenn die Range wörtlichen greifen auf die Eigenschaften des Arrays:

extension Array { 
    var myCount: Int { 
     print("myCount (\(self.count))") 
     return self.count 
    } 
    var myStartIndex: Int { 
     print("myStartIndex (\(self.startIndex))") 
     return self.startIndex 
    } 
    var myEndIndex: Int { 
     print("myEndIndex (\(self.endIndex))") 
     return self.endIndex 
    } 
} 

Wenn ich diese Eigenschaften anstelle der normalen diejenigen verwenden, die ich erhalten:

myCount (3) 
i: 0 count: 3 value: a 
i: 1 count: 3 value: b 
i: 2 count: 4 value: c 

und

myStartIndex (0) 
myEndIndex (3) 
i: 0 count: 3 value: a 
i: 1 count: 3 value: b 
i: 2 count: 4 value: c 
i: 3 count: 4 value: x 

ich etwas fehlen muss, weil diese wie Magie fühlt! Es scheint wie endIndex wird neu bewertet, aber count ist nicht. Was gibt? Diese

+0

'für i in dinge.indices {' oder wenn Sie nicht brauchen den Index 'für etwas in den Dingen {' –

Antwort

1

liegt daran, dass in dem ersten Teil des Codes, haben Sie verwenden die halboffenen Bereich Operator (..<), während im zweiten Teil des Codes Sie den normalen Bereich Operator verwendet (...). Sie sind unterschiedlich. Vom apple docs:

Der halboffenen Bereich Operator (a..<b) definiert einen Bereich, der von a nach b läuft, aber nicht b umfassen.

Also, die for Schleife in dem ersten Teil des Codes wird nicht fortgesetzt, wenn things.count 4 als Bereich (0-4), wenn sie mit dem halboffenen Bereich Operator nur verwendet, Schleife, wenn i 0, 1, 2 oder 3.

Wenn Sie ... anstelle von ..< verwenden, ist das Ergebnis des ersten Codeabschnitts identisch mit dem zweiten Code.

+0

Danke, dass Sie mich auf den Kopf schlagen - was für ein einfacher Fehler! Es scheint, dass die einzige Möglichkeit, über eine sich ändernde Sammlung zu iterieren, eine while-Schleife ist, da sie ihre Bedingung jedes Mal durch die Schleife auswertet. Ist das richtig - für Schleifen in Swift nur einmal auswerten? (Ich sage nicht, das ist eine gute Idee;) - nur versuchen, die Sprache zu lernen) – jibberia

Verwandte Themen