Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift different array behaviour with 'import Foundation'

When I run the following code I get the expected output:

var a = [1, 2, 3]
var b = a

if a === b { println("a === b") }
if a == b { println("a == b") }

Output:

a === b

a == b

However, if I import Foundation suddenly I only a new output:

import Foundation    

var a = [1, 2, 3]
var b = a

if a === b { println("a === b") }
if a == b { println("a == b") }

Output:

a == b

Does anyone know what is going on behind the scenes? Thank you.

like image 577
will.fiset Avatar asked Jun 10 '14 19:06

will.fiset


1 Answers

It has to do with mutability, though the import Foundation part is interesting. My guess is that it has to do with NSArray or NSObject copying.

You can test it by changing your var to let and watching === become true again.

Test the different permutations and see what happens:

Both Mutable

var a = [1, 2, 3]
var b = a

if a === b { println("arrays are the same instance") }  // false
if a == b { println("arrays are equivalent") }  // true

Mutable Source, Immutable Copy

var a = [1, 2, 3]
let b = a

if a === b { println("arrays are the same instance") }  // false
if a == b { println("arrays are equivalent") }  // true

Immutable Source, Mutable Copy

let a = [1, 2, 3]
var b = a

if a === b { println("arrays are the same instance") }  // false
if a == b { println("arrays are equivalent") }  // true

Both Immutable

let a = [1, 2, 3]
let b = a

if a === b { println("arrays are the same instance") }  // true
if a == b { println("arrays are equivalent") }  // true

This is actually the proper behavior for making a defensive copy, only when necessary.

If your source is mutable, you have to make a copy otherwise changes could be made externally. If you want a mutable copy you need to make a copy of course.

The only time a copy is not made is when both the source and copy are immutable, because that would be wasteful.

like image 195
Erik Avatar answered Nov 06 '22 23:11

Erik