Неизменяемые / изменчивые коллекции в Swift
Я имел в виду руководство по программированию Apple Swift для понимания создания изменяемых / неизменяемых объектов (Array, Dictionary, Sets, Data) на языке 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"];
7 ответов
Массивы
Создать неизменный массив
Первый способ:
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"
У Swift нет ни капли в замене NSArray
или другие классы коллекции в Objective-C.
Существуют классы массивов и словарей, но следует отметить, что это типы "значения" по сравнению с NSArray и NSDictionary, которые являются типами "объект".
Разница невелика, но может быть очень важной, чтобы избежать ошибок в крайнем случае.
В swift вы создаете "неизменяемый" массив с:
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"]
Переписал этот ответ 2015-08-10, чтобы отразить текущее поведение Swift.
Здесь только один Array
и один Dictionary
введите Свифт. Изменчивость зависит от того, как вы ее построите:
var mutableArray = [1,2,3]
let immutableArray = [1,2,3]
т.е. если вы создаете присвоение переменной, оно является изменчивым, тогда как если вы создаете присвоение константе, это не так.
ВНИМАНИЕ: неизменяемые массивы не являются полностью неизменяемыми! Вы все еще можете изменить их содержимое, но не их общую длину!
Просто объявите свой (любой) объект или переменную с помощью
'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
Если вы хотите работать с Array
(Свифт) как с NSArray
, вы можете использовать простую функцию моста. Пример:
var arr1 : Array = []
arr1.bridgeToObjectiveC().count
Это работает так же для let
,
Из собственных документов Apple:
Изменчивость коллекций
Если вы создаете массив, набор или словарь и присваиваете его переменной, созданная коллекция будет изменчивой. Это означает, что вы можете изменить (или изменить) коллекцию после ее создания, добавляя, удаляя или изменяя элементы в коллекции. И наоборот, если вы присваиваете константу массив, набор или словарь, эта коллекция является неизменной, и ее размер и содержимое не могут быть изменены.
Другое использование неизменяемых / изменяемых коллекций зависит от того, почему вы хотите, чтобы они были изменяемыми / неизменяемыми. Коллекции являются типами значений в Swift, что означает, что их содержимое копируется, когда они присваиваются другому значению или передаются другой функции / методу. Следовательно, вам не нужно беспокоиться о том, может ли функция-получатель изменить исходный массив. Поэтому вам не нужно возвращать неизменяемую коллекцию, например, если ваш класс содержит изменяемую коллекцию.
Массив Swift можно отключить
[let vs var, значение vs тип ссылки]
Неизменяемая коллекция [О программе] - это коллекция, структура которой не может быть изменена. Это означает, что вы не можете добавлять, удалять, изменять после создания
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
массив
Там нет встроенного актерского состава для этого. Но вместо этого вы можете использовать инициализатор NSMutableDictionary, который принимает словарь:
var foundationDictionary = NSMutableDictionary(dictionary: dictionary)