Swift'de Değişmez / Değişebilir Koleksiyonlar


88

Değişken / değişmez nesnelerin (Dizi, Sözlük, Kümeler, Veri) Swift dilinde oluşturulmasını anlamak için Apple'ın Swift programlama kılavuzuna başvuruyordum. Ancak Swift'de nasıl değişmez bir koleksiyon oluşturacağımı anlayamadım.

Objective-C'de aşağıdakiler için Swift'deki eşdeğerlerini görmek istiyorum

Değişmez Dizi

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

Değişebilir Dizi

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

Değişmez Sözlük

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

Değişken Sözlük

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

Yanıtlar:


115

Diziler

Değişmez dizi oluşturun

İlk yol:

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

İkinci yol:

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

Değiştirilebilir dizi oluştur

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

Diziye nesne ekle

array.append("Forth")


Sözlükler

Değişmez sözlük oluşturun

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

Değiştirilebilir sözlük oluştur

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

Sözlüğe yeni çift ekle

dictionary["Item 3"] = "description"

Apple Developer hakkında daha fazla bilgi


12
"Sabit uzunluk" dizisi daha kesin olacaktır. Değişmez değil.
Sulthan

1
immutable Dictionarygerçekten değişmez (Array'in tersi)
Bryan Chen

@BryanChen Oh .. Teşekkürler!
nicael

@BryanChen Evet, kaldırmayı unuttum var.
nicael

2
Evet. Bu soru ve yanıtlarında dizilerin değişmezliği hakkında daha fazla bilgi .
Matt Gibson

31

Swift, NSArrayObjective-C'deki diğer koleksiyon sınıflarının yerine geçmez .

Dizi ve sözlük sınıfları vardır, ancak bunların "nesne" türleri olan NSArray ve NSDictionary ile karşılaştırıldığında "değer" türleri olduğuna dikkat edilmelidir.

Aradaki fark ince ancak uç durum hatalarından kaçınmak için çok önemli olabilir.

Hızlıda, aşağıdakilerle "değişmez" bir dizi oluşturursunuz:

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

Ve aşağıdakileri içeren "değiştirilebilir" bir dizi:

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

Değişken diziler aşağıdaki gibi değiştirilebilir NSMutableArray:

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

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

Ancak, değişebilir bir diziyi bir işleve geçiremezsiniz:

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

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

Ancak yukarıdaki kod bir NSMutableArray ile çalışır:

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

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

addToArray(myArray)

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

NSMutableArrayBir inoutyöntem parametresi kullanarak davranışını elde edebilirsiniz :

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

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

addToArray(&myArray)

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

Mevcut Swift davranışını yansıtmak için 2015-08-10 bu yanıtı yeniden yazdı.


1
Bu açıkça şimdi değiştirildi. Sabit bir dizi artık gerçekten değişmez ve bir değişken dizi artık gerçekten değiştirilebilir. Bunlar geçirilen değerlerle başka değişkene atanan veya fonksiyonlar arasında geçtiğinde bu nedenle kopyalanacaktır. Ancak bunun değişkenlik veya değişmezlik ile hiçbir ilgisi yoktur.
Balthazar

Ayrıca cevabımda bahsettiğim gibi, değer olarak iletilmek, değişkenlik / değişmezlik ile ilgilidir çünkü bunu önemsediğiniz tek zaman bir diziyi başka bir koda geçirmektir (bu onu değiştirebilir).
Abhi Beckert

Ancak diziye bir özellik olarak erişirseniz, onu başka bir nesneden yine de değiştirebilirsiniz. Değişmez bir dizinin faydalarından biri, diğer nesnenin orijinali değiştirip değiştirmeyeceği konusunda endişelenmeden, onu başka bir nesneye güvenli bir şekilde aktarabilmenizdir. Nesneler değer olarak aktarıldığında bu endişe artık mevcut değildir. Bu nedenle, farklı anlambilim, farklı kodlama uygulamaları gerektirir. DÜZENLEME: Şimdi gönderiyi yeniden yazdığınızı görüyorum, bu yüzden kabul ediyoruz. Farkların farkında olmanın önemli olduğuna katılıyorum. değiştirilebilir koleksiyonların kullanımı.
Balthazar

6

Swift'de sadece bir Arrayve bir Dictionarytür var. Değişebilirlik, onu nasıl oluşturduğunuza bağlıdır:

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

yani, bir değişkene bir atama oluşturursanız, değişebilir, oysa sabite bir atama oluşturursanız, değildir.

UYARI: Değişmez diziler tamamen değişmez değildir! Yine de içeriklerini değiştirebilirsiniz, ancak toplam uzunluklarını değiştiremezsiniz!


1
Bilginize: dizi davranışı gelecek bir beta sürümde değişiyor; Sanırım herkes bunun üzerine yığıldı
russbishop

@xenadu Kaynak? O betada tahmini varış süresi?
Analog Dosya

Üzgünüm, kaynak yok. Derleyici ekip üyelerinden biriyle yapılan bir tartışmadan geldi. Ayrıca Beta 2'nin temelde yalnızca birkaç hata düzeltmesi yapıldığını ve WWDC sonrası geri bildirimlerle ilgili hiçbir şey olmadığını söyledi.
russbishop

5

Sadece (herhangi bir) nesnenizi veya değişkeninizi

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

ve

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

Daha derin bilgi için

“Kullanım let bir sabiti ve yapmaya Var bir değişken yapmak. Bir sabitin değerinin derleme sırasında bilinmesi gerekmez, ancak ona tam olarak bir kez değer atamanız gerekir. Bu, bir kez belirlediğiniz ancak birçok yerde kullandığınız bir değeri adlandırmak için sabitleri kullanabileceğiniz anlamına gelir. "

var myVariable = 42
myVariable = 50
let myConstant = 42

"Swift Programlama Dili" ni okuyun.


Bir Array durumunda bu beklendiği gibi çalışmaz. stackoverflow.com/a/24319712/623710
macshome

3

Birlikte çalışmak istiyorsanız Arrayolduğu gibi (Swift) NSArray, basit bir köprü işlevini kullanabilirsiniz. Misal:

var arr1 : Array = []

arr1.bridgeToObjectiveC().count

Aynı şekilde çalışır let.


0

Apple'ın kendi belgelerinden:

Koleksiyonların Değişebilirliği

Bir dizi, küme veya sözlük oluşturur ve bunu bir değişkene atarsanız, oluşturulan koleksiyon değiştirilebilir olacaktır. Bu, koleksiyonu oluşturduktan sonra koleksiyondaki öğeleri ekleyerek, kaldırarak veya değiştirerek değiştirebileceğiniz (veya değiştirebileceğiniz) anlamına gelir. Tersine, bir sabite bir dizi, küme veya sözlük atarsanız, bu koleksiyon değişmezdir ve boyutu ve içeriği değiştirilemez.

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

Değişmez / değiştirilebilir koleksiyonların diğer kullanımları, neden onların değiştirilebilir / değiştirilemez olmasını istediğinize bağlıdır. Koleksiyonlar, Swift'deki değer türleridir, yani içerikleri başka bir değere atandığında veya başka bir işleve / yönteme aktarıldığında kopyalanır. Bu nedenle, bir alma yöntemi işlevinin orijinal diziyi değiştirip değiştirmeyeceği konusunda endişelenmenize gerek yoktur. Bu nedenle, örneğin, sınıfınız değiştirilebilir bir koleksiyon tutuyorsa, değişmez bir koleksiyon döndürdüğünüzden emin olmanıza gerek yoktur.


0

[Değiştirilemez ve Değiştirilemez]

Swift'in dizisi kapatılabilir

[let - var, Değer - Referans Türü]

Immutable collection [Hakkında] - değiştirilemeyen bir koleksiyon yapısıdır. Oluşturduktan sonra ekleyemeyeceğiniz, kaldıramayacağınız, değiştiremeyeceğiniz anlamına gelir

let + struct(gibi Array, Set,Dictionary ) iletmenin olması daha uygundur

NSArrayİç durumu değiştirmek için bir arayüz sağlamayan bazı sınıflar (örneğin ) vardır.

fakat

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)
}   

Oldukça olduğunu olurdu unmodifiabledizi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.