How should I reason when I have to choose between a class, struct and enum in Swift?

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

enter image description here


For starters, Classes are pass-by-reference and Structs are pass-by-copy.

enums are still a special type to specify, well, enumerations. They should be used just like before.

In general, the choice of Class vs Structs shouldn't be much different than before. Classes are still fit for larger/complex objects and Structs are good for small, isolated model objects. The fact that structs have protocols and such now should just serve to simplify your code and make it more efficient.

Tags:

Swift