Since classes, structs and enums all has constructors, properties and computed properties, how should I reason when choosing between them?
Classes are reference types, and structs are value types. If class inheritance is not needed, structs are faster and more memory efficient. Use structs for unique copies of an object with independent states. Use structs when working with a few, relatively simple data values.
Structs are preferable if they are relatively small and copiable because copying is way safer than having multiple references to the same instance as happens with classes. This is especially important when passing around a variable to many classes and/or in a multithreaded environment.
Coming from an objective c background, the difference between components like enums, classes, and structs was quite obvious for me: An Enum is a set of named values, Struct is structured data type, and of course Class allows us to create objects with all POO related stuff.
ChristopheD's and Jack Wu's answers are good, but I feel they don't touch on enums, or miss their importance. Swift enums are (meant to be) a full implementation of algebraic data types. Classes and structs are traditionally used to model data in object-oriented languages, but enums are usually limited to being used as a convenient way to limit the value of a variable to a limited number of possibilities. E.g. (C++):
enum MaritalStatus { Unmarried, Married, Divorced, WidowedOrWidowered };
MaritalStatus m = Unmarried;
Swift enums can do the above but they can do a lot more. Of course the Language Guide has a pretty good barcode modelling example but the best example I know of that really drives home the point of modelling data with algebraic data types is Scott Wlaschin's presentation: http://www.slideshare.net/ScottWlaschin/ddd-with-fsharptypesystemlondonndc2013
You would probably benefit from going through the whole presentation but really to 'get' the point all you need to see is slide 60 where he shows how to model a 'payment method' in a typical line-of-business app.
The examples in the presentation are in F# but F# isn't that far off from Swift and you can pretty easily map between them. E.g., the payment methods enum in Swift would look like:
enum PaymentMethod {
case cash // No extra data needed.
case cheque(Int) // Cheque #.
case card(CardType, CardNumber) // 2 pieces of extra data.
}
The point of the above is that each order's payment method can be only one of the above three methods. Anything else will not be allowed by the compiler. This is a very succinct alternative to building entire class hierarchies to model these almost trivial things.
The presentation really takes off from there and the best part is Swift can do almost everything that F# can in terms of data modelling, using optional types, etc.
Besides the advice on the practical usage of class, struct and enum, here is the comparison that clarifies the abilities among them Swift Classes, Structs, Enums, and Tuples compared
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With