Now that I have cleared a few things from my queue, I have some time and mental energy to really delve into some of the things I left on my back burner. One of those things is to really dive deeply into Swift.
Yes, I know. I have my name on a book using Swift. That book isn’t a language book, it is a framework book. We are primarily getting people who code familiar with the Cocoa Touch frameworks that most people will use. We did not really dive deeply into the minutiae of the Swift Language because, honestly, very few people have. It is still in the process of changing and many people are still stuck in the mental paradigm that they are supposed to write it like they would Objective-C.
I knew when I was going to learn Swift that I really wanted to grok in fullness how best to use the language and to not write hacked, inefficient, and messy code.
One thing I am trying to get used to is the fact that a file does not have to have a class. I am so used to the idea that every file must not only have a class, but that the class must have the same name as the file that seeing it is possible to write a file without that and have it compile kind of blows my mind.
This begs the question in my mind of what do you, or should you, need to include in a file that integrates into your project. Right now I am focusing on three different structures: classes, structs, and enums. I want to explore what each of them gives you and what their limitations are. These are three very similar things and I am interested in exploring what situations each would work it.
This post will be on structures and classes and a future post will be on enums.
Class Versus Structure
Classes have all the same functionality that structures have, but this does not go the other way around. Classes and structures can both do the following:
- Define properties
- Define methods
- Define subscripts to provide access using subscript syntax
- Define initializers
- Be extended and expanded
- Conform to protocols
Structures are far more powerful here in Swift than they were back in the Objective-C days. Back in the day structures could pretty much just do the first thing in this list, define properties. Structures have taken on some of the heavy lifting that only classes used to do.
Classes, on the other hand, can do all of these things along with the following:
- Inherit characteristics
- Check and interpret the class type through type casting
- Deinitialize resources
- Allow more than one reference to the class instance
This kind of begs the question of why you would create a struct if you can get all the functionality of one for “free” by creating a class. What are the advantages of a struct? Why did the Swift development team think it was necessary to supercharge the struct type?
We would of course want to create a struct in the same situations we used to use them before. But if a struct can conform to a protocol, be extended, and define methods, then where is the line between a class and a struct?
One of the things in this list confused me somewhat: ”Define subscripts to provide access using subscript syntax.” I am perusing the Apple documentation and apparently this means that if you instantiate a struct in a class, you can directly set one property inside the struct. I didn’t use structs much when I was learning Objective-C, but I vaguely remember if you created an instance of a struct, like CGRect, you had to set both aspects of the CGRect. You couldn’t create a CGRect that was a square, change your mind, and just reset the length to be longer. You had to reset the height as well. Now if you wanted to do that, you could simply specify the parameter you want to change and reset it directly.
Structures and enums are both value types, but classes are not. A value type is a type whose value is copied when you assign it or pass it around. I didn’t know this, but all the types that we use in Swift, like integers, Boolians, and strings, are all actually implemented as structures. I am so used to dealing with these “primitive” data types that I never thought about how they get implemented by the compiler. I find it fascinating that all the types we use in Swift boil down to structures.
I guess if you really think about what the code is doing, this makes total sense. We are not using C pointers in Swift. If you create a CGRect and then create a second one that is set to the same initial value as the first one, your second CGRect can change and mutate independently of the first CGRect.
Classes are reference types. This means that if you create an instance of a class then set another instance of the same class to the first instance, they are linked and what affects one will affect the other. This is a really important distinction between a class and a structure. If you have something where you will need to create a lot of instances of that object, but you want them to display slightly different behavior, you would want to use a structure. Likewise, if you want a lot of instances that will all change when one changes, you would use a class.
So When Do I Use A Structure?
Here is Apple’s advice about when you would want to use a structure. They advise you do to so if at least three of the following conditions apply:
- You are encapsulating a few relatively simple data values
- Your values must be copied rather than referenced when they are passed around
- Any properties in the structure are value types, or if you are not storing instances of classes
- The structure does not need to inherit properties or behaviors from an existing type
This list is…interesting…
The problem I am having here is that this is pretty much what you could do with structures back in C and Objective-C. What was the point of really increasing the scope of what they can do just to advise everyone to treat them like they did before. This puzzles me. I thought by exploring these differences that I would uncover something I hadn’t considered before, but I am left with my initial questions.
It’s possible I am reading too much into this. Being an Apple developer means sifting through everything Apple says to try and read the tea leaves of what direction they are going in next. Sometimes they leave a decent trail of breadcrumbs. Sometimes they don’t.
I am in the parallel process of learning Haskell along with Swift. I am going to keep these questions in the back of my mind to see if I can find any more answers to this question in other locations. I feel there is something significant here I haven’t gleaned yet, and I am looking forward to figuring out what it is.
I hope for this to be the first in a series of posts about the Swift programming language and how to work with it most effectively. I am probably not telling anyone anything they couldn’t figure out from reading Apple’s Swift book. I have found that writing things out as I am learning them is helpful to my own learning process. If my writing is helpful to you as well, awesome.