I have recently begun learning swift 2.0, because I would like to build an iOS app and I really don't want to have to learn Objective-C. I am trying to learn it the right way, which means understanding how the language works and not just mutating examples to learn by accident.
I have been reading a lot about structs and classes, and the difference between value types and reference types. In short, classes pass around object references and structs make copies whenever you pass them around. I visualize it in old-school terms: Classes use pointers, but with structs the variable IS the data.
This seems pretty simple - especially if you are comfortable with object languages. I have watched a few Apple videos, though, and they make it sound revolutionary.
This one in particular goes on about unintended sharing - I pass a handle to the same object into two different contexts where they are expected to be independent. Change one, impact the other, etc. His illustrative example was "I created a thermostat object, assigned it to my house. Then I set the thermostat in my oven to 450, and my house caught on fire!"
Paraphrase. Gag - what a juvenile way to introduce a language feature. They could have at least used a real-world scenario they came across implementing their standard libraries that made this feature such a deal-maker.
This seems to me to be very valuable to a college student, or someone learning an object language coming from C, but really, is this that big of a deal? I can honestly say that I haven't had a bug of this type in my code, that I have detected of course - for
decades. On the other hand, I just spent an agonizing couple of days trying to figure out why extremely routine code did not work. Take this example:
var map = [String: [String: String]]();
var subMap = [String: String]();
map["map"] = subMap;
subMap["1"] = "2";
For those who don't know swift, this means create a map which can hold maps of string value/pairs. Next, create a string value/pair map, and assign it to the key "map" in the top-level map. Finally, assign the key/value entry "1" -> "2" into the sub map. The expectation being that it will be reflected in the top-level map as well. This is pretty standard in Java - I do it a lot so I can factor code which handles the sub trees into external code. In this case, it doesn't work. Because collections in swift are structs - I.E., value types - the assignment on the third line makes a copy which is unaffected by the assignment on line 4. I came up with this working code after much hair-pulling:
var map: Dictionary = [String: [String: String]]();
map["map"]!["1"] = "2";
And only later uncovered the reason that I explained before. I find this extremely annoying, but certainly manageable once you understand the language - and maybe even something you can use effectively. But I found his example so contrived that I basically checked out.