Unveränderliche / veränderbare Sammlungen in Swift

87

Ich bezog mich auf Apples Swift-Programmierhandbuch, um die Erstellung von veränderlichen / unveränderlichen Objekten (Array, Wörterbuch, Mengen, Daten) in Swift-Sprache zu verstehen. Aber ich konnte nicht verstehen, wie man in Swift unveränderliche Sammlungen erstellt.

Ich würde gerne die Entsprechungen in Swift für das Folgende in Ziel-C sehen

Unveränderliches Array

NSArray *imArray = [[NSArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];

Veränderbares Array

NSMutableArray *mArray = [[NSMutableArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];
[mArray addObject:@"Fourth"];

Unveränderliches Wörterbuch

NSDictionary *imDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];

Veränderbares Wörterbuch

NSMutableDictionary *mDictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];
[mDictionary setObject:@"Value3" forKey:@"Key3"];
Pranav Jaiswal
quelle

Antworten:

115

Arrays

Erstellen Sie ein unveränderliches Array

Erster Weg:

let array = NSArray(array: ["First","Second","Third"])

Zweiter Weg:

let array = ["First","Second","Third"]

Erstellen Sie ein veränderliches Array

var array = ["First","Second","Third"]

Objekt an Array anhängen

array.append("Forth")


Wörterbücher

Erstellen Sie ein unveränderliches Wörterbuch

let dictionary = ["Item 1": "description", "Item 2": "description"]

Erstellen Sie ein veränderliches Wörterbuch

var dictionary = ["Item 1": "description", "Item 2": "description"]

Neues Paar an Wörterbuch anhängen

dictionary["Item 3"] = "description"

Weitere Informationen zu Apple Developer

nicael
quelle
12
Das Array "Feste Länge" wäre genauer. Es ist nicht unveränderlich.
Sulthan
1
unveränderlich Dictionaryist wirklich unveränderlich (im Gegensatz zu Array)
Bryan Chen
@BryanChen Oh .. Danke!
Nicael
@BryanChen Ja, ich habe vergessen zu entfernen var.
Nicael
2
Jep. Weitere Informationen zur Unveränderlichkeit von Arrays in dieser Frage und ihren Antworten .
Matt Gibson
31

Swift hat keinen Ersatz für NSArrayoder für die anderen Sammlungsklassen in Objective-C.

Es gibt Array- und Wörterbuchklassen, aber es sollte beachtet werden, dass dies "Wert" -Typen sind, verglichen mit NSArray und NSDictionary, die "Objekt" -Typen sind.

Der Unterschied ist subtil, kann aber sehr wichtig sein, um Edge-Case-Fehler zu vermeiden.

In Kürze erstellen Sie ein "unveränderliches" Array mit:

let hello = ["a", "b", "c"]

Und ein "veränderliches" Array mit:

var hello = ["a", "b", "c"]

Veränderbare Arrays können wie folgt geändert werden NSMutableArray:

var myArray = ["a", "b", "c"]

myArray.append("d") // ["a", "b", "c", "d"]

Sie können jedoch kein veränderbares Array an eine Funktion übergeben:

var myArray = ["a", "b", "c"]

func addToArray(myArray: [String]) {
  myArray.append("d") // compile error
}

Der obige Code funktioniert jedoch mit einem NSMutableArray:

var myArray = ["a", "b", "c"] as NSMutableArray

func addToArray(myArray: NSMutableArray) {
  myArray.addObject("d")
}

addToArray(myArray)

myArray // ["a", "b", "c", "d"]

Sie können NSMutableArraydas Verhalten mithilfe eines inoutMethodenparameters erreichen:

var myArray = ["a", "b", "c"]

func addToArray(inout myArray: [String]) {
  myArray.append("d")
}

addToArray(&myArray)

myArray // ["a", "b", "c", "d"]

Diese Antwort wurde am 10.08.2015 neu geschrieben, um das aktuelle Swift-Verhalten widerzuspiegeln.

Abhi Beckert
quelle
1
Dies wurde offensichtlich jetzt geändert. Ein konstantes Array ist jetzt wirklich unveränderlich, und ein variables Array ist jetzt wirklich veränderlich. Sie werden als Werte übergeben , daher werden sie kopiert, wenn sie einer anderen Variablen zugewiesen oder zwischen Funktionen übergeben werden. Dies hat jedoch nichts mit Veränderlichkeit oder Unveränderlichkeit zu tun.
Balthazar
Wie ich in meiner Antwort erwähnt habe, ist die Übergabe als Werte für die Veränderlichkeit / Unveränderlichkeit relevant, da Sie sich nur darum kümmern, wenn Sie ein Array an einen anderen Code übergeben (der es möglicherweise ändert).
Abhi Beckert
Wenn Sie jedoch als Eigenschaft auf das Array zugreifen, können Sie es dennoch von einem anderen Objekt aus ändern. Einer der Vorteile eines unveränderlichen Arrays besteht darin, dass Sie es sicher an ein anderes Objekt übergeben können, ohne sich Sorgen machen zu müssen, ob das andere Objekt das Original ändern könnte. Dieses Problem besteht nicht mehr, wenn die Objekte als Werte übergeben werden. Unterschiedliche Semantiken erfordern daher unterschiedliche Codierungspraktiken. EDIT: Ich sehe jetzt, dass Sie den Beitrag umformuliert haben, also sind wir uns einig. Ich bin damit einverstanden, dass die Unterschiede wichtig sind, um sich dessen bewusst zu sein. die Verwendung von veränderlichen Sammlungen.
Balthazar
6

Es gibt nur einen Arrayund einen DictionaryTyp in Swift. Die Veränderlichkeit hängt davon ab, wie Sie es konstruieren:

var mutableArray = [1,2,3]
let immutableArray = [1,2,3]

Wenn Sie also eine Zuweisung zu einer Variablen erstellen, ist diese veränderbar, während dies beim Erstellen einer Zuweisung zu einer Konstanten nicht der Fall ist.

WARNUNG: Unveränderliche Arrays sind nicht vollständig unveränderlich! Sie können ihren Inhalt immer noch ändern, nur nicht ihre Gesamtlänge!

ColinE
quelle
1
Zu Ihrer Information: Das Array-Verhalten ändert sich in einer kommenden Beta. Ich denke, jeder hat sich über diesen einen
Gedanken gemacht
@ Xenadu Quelle? ETA in dieser Beta?
Analoge Datei
Entschuldigung, keine Quelle. Es kam aus einer Diskussion mit einem der Compiler-Teammitglieder. Er sagte auch, dass Beta 2 im Grunde nur ein paar bereits eingecheckte Fehlerkorrekturen waren und nichts mit dem Feedback nach dem WWDC zu tun haben.
Russbischof
5

Deklarieren Sie einfach Ihr (beliebiges) Objekt oder Ihre Variable mit

'let' key word -> for "constan/Immutable" array, dictionary, variable, object..etc.

und

'var' key word -> for "Mutable" array, dictionary, variable, object..etc. 

Für tiefere Informationen

„Verwenden Sie let , um eine Konstante zu erstellen , und var , um eine Variable zu erstellen. Der Wert einer Konstante muss zur Kompilierungszeit nicht bekannt sein, aber Sie müssen ihr genau einmal einen Wert zuweisen. Dies bedeutet, dass Sie Konstanten verwenden können, um einen Wert zu benennen, den Sie einmal bestimmen, aber an vielen Stellen verwenden. "

var myVariable = 42
myVariable = 50
let myConstant = 42

Lesen Sie „Die schnelle Programmiersprache“.

iPatel
quelle
Nun, im Fall eines Arrays funktioniert dies nicht wie erwartet. stackoverflow.com/a/24319712/623710
macshome
3

Wenn Sie mit Array(Swift) wie mit arbeiten möchten NSArray, können Sie eine einfache Bridge-Funktion verwenden. Beispiel:

var arr1 : Array = []

arr1.bridgeToObjectiveC().count

Es funktioniert genauso für let.

Moti F.
quelle
0

Aus Apples eigenen Dokumenten:

Veränderlichkeit von Sammlungen

Wenn Sie ein Array, eine Menge oder ein Wörterbuch erstellen und einer Variablen zuweisen, kann die erstellte Sammlung geändert werden. Dies bedeutet, dass Sie die Sammlung nach ihrer Erstellung ändern (oder mutieren) können, indem Sie Elemente in der Sammlung hinzufügen, entfernen oder ändern. Wenn Sie dagegen einer Konstante ein Array, eine Menge oder ein Wörterbuch zuweisen, ist diese Sammlung unveränderlich und ihre Größe und ihr Inhalt können nicht geändert werden.

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID105

Andere Verwendungen von unveränderlichen / veränderlichen Sammlungen hängen davon ab, warum sie veränderlich / unveränderlich sein sollen. Kollektionen sind Werttypen in Swift, was bedeutet , dass ihr Inhalt kopiert wird , wenn sie auf einen anderen Wert zugeordnet sind, oder auf eine andere Funktion / Methode übergeben. Daher müssen Sie sich keine Gedanken darüber machen, ob eine Empfangsmethodenfunktion das ursprüngliche Array ändern könnte. Daher müssen Sie nicht sicherstellen, dass eine unveränderliche Sammlung zurückgegeben wird, wenn Ihre Klasse beispielsweise eine veränderbare Sammlung enthält.

Balthazar
quelle
0

[Nicht veränderbar und unveränderlich]

Das Array von Swift kann stummgeschaltet werden

[let vs var, Wert vs Referenztyp]

Unveränderliche Sammlung [Info] - ist eine Sammlungsstruktur, deren Änderungen nicht geändert werden können. Dies bedeutet, dass Sie nach der Erstellung keine hinzufügen, entfernen oder ändern können

let + struct(wie Array, Set, Dictionary) ist besser geeignet zu sein unveränderliche

Es gibt einige Klassen (z. B. NSArray), die keine Schnittstelle zum Ändern des inneren Zustands bieten

aber

class A {
    var value = "a"
}

func testMutability() {
    //given
    let a = A()
    
    let immutableArr1 = NSArray(array: [a])
    let immutableArr2 = [a]
    
    //when
    a.value = "aa"
    
    //then
    XCTAssertEqual("aa", (immutableArr1[0] as! A).value)
    XCTAssertEqual("aa", immutableArr2[0].value)
}   

Es wäre lieber unmodifiableArray

yoAlex5
quelle
-2

Dafür gibt es keine eingebaute Besetzung. Stattdessen können Sie den Initialisierer von NSMutableDictionary verwenden, der ein Wörterbuch verwendet:

var foundationDictionary = NSMutableDictionary(dictionary: dictionary)
Ved Rauniyar
quelle