Незмінні / змінні колекції в Swift


88

Я мав на увазі посібник програмування Swift від Apple, щоб зрозуміти створення змінних / незмінних об’єктів (масив, словник, набори, дані) мовою Swift. Але я не міг зрозуміти, як створити незмінні колекції в Swift.

Я хотів би бачити еквіваленти в Swift для наступного в Objective-C

Незмінний масив

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

Змінний масив

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

Незмінний словник

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

Змінюваний словник

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

Відповіді:


115

Масиви

Створити незмінний масив

Перший спосіб:

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

Другий спосіб:

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

Створити змінний масив

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

Додати об’єкт до масиву

array.append("Forth")


Словники

Створити незмінний словник

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

Створіть змінний словник

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

Додати нову пару до словника

dictionary["Item 3"] = "description"

Більше інформації про розробника Apple


12
Масив "Фіксована довжина" був би точнішим. Це не є незмінним.
Султан

1
незмінний Dictionaryпо-справжньому незмінний (навпроти Array)
Брайан Чен,

@BryanChen О .. Дякую!
Нікаел

@BryanChen Так, я забув видалити var.
nicael

2
Так. Більше інформації про незмінність масивів у цьому питанні та відповіді на нього .
Метт Гібсон,

31

Swift не зазнав жодного зменшення заміни NSArrayабо інших класів колекцій у Objective-C.

Існують класи масивів та словників, але слід зазначити, що це типи "значення", порівняно з NSArray та NSD Dictionary, які є "об'єктом".

Різниця незначна, але може бути дуже важливою, щоб уникнути крайових помилок.

Швидко ви створюєте "незмінний" масив з:

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

І "змінний" масив із:

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

Змінювані масиви можна модифікувати так само, як NSMutableArray:

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

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

Однак ви не можете передати змінний масив функції:

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

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

Але наведений вище код працює з NSMutableArray:

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

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

addToArray(myArray)

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

Ви можете досягти NSMutableArrayповедінки користувача, використовуючи inoutпараметр методу:

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

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

addToArray(&myArray)

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

Переписав цю відповідь 10.08.2015, щоб відобразити поточну поведінку Свіфта.


1
Зараз це, очевидно, було змінено. Константний масив тепер справді незмінний, а змінний масив справді незмінний. Вони передаються як значення , тому їх буде скопійовано при призначенні іншій змінній або передачі між функціями. Однак це не має нічого спільного з мінливістю чи незмінністю.
Бальтазар

Також, як я вже згадував у своїй відповіді, передача як значення має відношення до змінності / незмінності, оскільки єдиний раз, коли ви дбаєте про це, - це передача масиву іншому коду (який може його змінити).
Абхі Беккерт,

Але якщо ви отримуєте доступ до масиву як властивість, ви все одно можете змінити його з іншого об’єкта. Однією з переваг незмінного масиву є те, що ви можете безпечно передати його іншому об’єкту, не турбуючись, чи може інший об’єкт змінити оригінал. Це занепокоєння вже не існує, коли об'єкти передаються як значення. Отже, різна семантика вимагає різної практики кодування. РЕДАГУВАТИ: Я бачу, що Ви переформулювали пост, тож ми погоджуємось. Я погоджуюсь, що відмінності важливі, щоб знати про wrt. використання змінних колекцій.
Бальтазар

6

У Swift є лише один Arrayі один Dictionaryтип. Змінюваність залежить від способу її побудови:

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

тобто, якщо ви створюєте присвоєння змінній, вона змінюється, тоді як якщо ви створюєте присвоєння константі, це не так.

ПОПЕРЕДЖЕННЯ: незмінні масиви не є повністю незмінними! Ви все ще можете змінити їх вміст, лише не загальну довжину!


1
FYI: поведінка масиву змінюється в майбутній бета-версії; Думаю, всі нагромадились на цьому
єпископ

@xenadu Джерело? ETA на цій бета-версії?
Аналоговий файл

Вибачте, джерела немає. Це сталося в результаті дискусії з одним із членів групи упорядників. Він також сказав, що Beta 2 в основному була лише парою вже перевірених виправлень помилок і не має нічого, що стосується відгуків після WWDC.
russbishop

5

Просто оголосіть свій (будь-який) об'єкт або змінну за допомогою

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

і

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

Для більш глибокої інформації

“Використовуйте let для створення константи, а var для створення змінної. Значення константи не потрібно знати під час компіляції, але ви повинні призначити їй значення рівно один раз. Це означає, що ви можете використовувати константи, щоб назвати значення, яке ви визначили один раз, але використовуєте в багатьох місцях ".

var myVariable = 42
myVariable = 50
let myConstant = 42

Прочитайте "Швидку мову програмування".


Ну, у випадку з масивом це працює не так, як очікувалося. stackoverflow.com/a/24319712/623710
macshome

3

Якщо ви хочете працювати з Array(Swift), як і з NSArray, ви можете використовувати просту функцію мосту. Приклад:

var arr1 : Array = []

arr1.bridgeToObjectiveC().count

Він працює однаково для let.


0

З власних документів Apple:

Змінність колекцій

Якщо ви створите масив, набір або словник і призначите його змінній, створена колекція буде змінною. Це означає, що ви можете змінити (або змінити) колекцію після її створення, додавши, видаливши або змінивши елементи в колекції. І навпаки, якщо ви призначите константі масив, набір або словник, ця колекція є незмінною, і її розмір та вміст не можна змінити.

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

Інші способи використання незмінних / змінних колекцій залежать від того, чому ви хочете, щоб вони були змінними / незмінними. Колекції - це типи значень у Swift, що означає, що їх вміст копіюється, коли їм присвоюється інше значення або передається інша функція / метод. Тому вам не потрібно турбуватися про те, чи може функція методу отримання змінити початковий масив. Тому вам не потрібно забезпечувати повернення незмінної колекції, якщо ваш клас, наприклад, має змінну колекцію.


0

[Немодифікований та незмінний]

Масив Свіфта можна вимкнути

[let vs var, Value vs Reference Reference]

Незмінна колекція [Про мене ] - це структура колекції, яку неможливо змінити. Це означає, що ви не можете додавати, видаляти, змінювати після створення

let + struct(Наприклад Array, Set, Dictionary) є більш відповідним , щоб бути незмінні

Є деякі класи (напр NSArray ), які не забезпечують інтерфейс для зміни внутрішнього стану

але

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

Швидше це unmodifiableмасив

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.