Immutable/Mutable Collections in Swift
I was referring to Apple's Swift programming guide for understanding creation of Mutable/ immutable objects(Array, Dictionary, Sets, Data) in Swift language. But I could't understand how to create a immutable collections in Swift.
I would like to see the equivalents in Swift for the following in Objective-C
Immutable Array
NSArray *imArray = [[NSArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];
Mutable Array
NSMutableArray *mArray = [[NSMutableArray alloc]initWithObjects:@"First",@"Second",@"Third",nil];
[mArray addObject:@"Fourth"];
Immutable Dictionary
NSDictionary *imDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];
Mutable Dictionary
NSMutableDictionary *mDictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil];
[mDictionary setObject:@"Value3" forKey:@"Key3"];
Solution 1:
Arrays
Create immutable array
First way:
let array = NSArray(array: ["First","Second","Third"])
Second way:
let array = ["First","Second","Third"]
Create mutable array
var array = ["First","Second","Third"]
Append object to array
array.append("Forth")
Dictionaries
Create immutable dictionary
let dictionary = ["Item 1": "description", "Item 2": "description"]
Create mutable dictionary
var dictionary = ["Item 1": "description", "Item 2": "description"]
Append new pair to dictionary
dictionary["Item 3"] = "description"
More information on Apple Developer
Solution 2:
Swift does not have any drop in replacement for NSArray
or the other collection classes in Objective-C.
There are array and dictionary classes, but it should be noted these are "value" types, compared to NSArray and NSDictionary which are "object" types.
The difference is subtle but can be very important to avoid edge case bugs.
In swift, you create an "immutable" array with:
let hello = ["a", "b", "c"]
And a "mutable" array with:
var hello = ["a", "b", "c"]
Mutable arrays can be modified just like NSMutableArray
:
var myArray = ["a", "b", "c"]
myArray.append("d") // ["a", "b", "c", "d"]
However you can't pass a mutable array to a function:
var myArray = ["a", "b", "c"]
func addToArray(myArray: [String]) {
myArray.append("d") // compile error
}
But the above code does work with an NSMutableArray:
var myArray = ["a", "b", "c"] as NSMutableArray
func addToArray(myArray: NSMutableArray) {
myArray.addObject("d")
}
addToArray(myArray)
myArray // ["a", "b", "c", "d"]
You can achieve NSMutableArray
's behaviour by using an inout
method parameter:
var myArray = ["a", "b", "c"]
func addToArray(inout myArray: [String]) {
myArray.append("d")
}
addToArray(&myArray)
myArray // ["a", "b", "c", "d"]
Re-wrote this answer 2015-08-10 to reflect the current Swift behaviour.
Solution 3:
There is only one Array
and one Dictionary
type in Swift. The mutability depends on how you construct it:
var mutableArray = [1,2,3]
let immutableArray = [1,2,3]
i.e. if you create an assign to a variable it is mutable, whereas if you create an assign to constant it is not.
WARNING: Immutable arrays are not entirely immutable! You can still change their contents, just not their overall length!
Solution 4:
Just declare your (any)object or variable with
'let' key word -> for "constan/Immutable" array, dictionary, variable, object..etc.
and
'var' key word -> for "Mutable" array, dictionary, variable, object..etc.
For more deeply information
“Use let to make a constant and var to make a variable. The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once. This means you can use constants to name a value that you determine once but use in many places."
var myVariable = 42
myVariable = 50
let myConstant = 42
Read “The Swift Programming Language.”
Solution 5:
If you want to work with Array
(Swift) as with NSArray
, you can use a simple bridge function. Example:
var arr1 : Array = []
arr1.bridgeToObjectiveC().count
It works the same for let
.