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

前端 未结 7 1792
感情败类
感情败类 2020-12-08 07:16

Since classes, structs and enums all has constructors, properties and computed properties, how should I reason when choosing between them?

相关标签:
7条回答
  • 2020-12-08 07:21

    Structures have memberwise initializers (class instances do not receive a default memberwise initializer)

    All structures have an automatically-generated memberwise initializer, which you can use to initialize the member properties of new structure instances. Initial values for the properties of the new instance can be passed to the memberwise initializer by name:

    let vga = Resolution(width: 640, height: 480)
    

    which makes perfect sense since they are value types (and thus immutable).

    Enumerations are value types too. Classes are reference types. No real surprises here.

    0 讨论(0)
  • 2020-12-08 07:27

    I think it's quite a refined discussion! I like the thoughts expressed here: http://www.swift-studies.com/blog/2014/7/1/struct-enum-or-class

    There's quite a lot of details, and their recommendations. I've copied their summary here, but it's a whole article

    • enums are initialised by one of a finite number of cases, are completely defined by their case, and should always be valid instances of that case when instantiated
    • structs should be used when there is not a finite number of valid instances (e.g. enum cases) and the struct also does not form a complete definition of an object, but rather an attribute of an object
    • A class completely defines a primary actor in your object model, both its attributes and its interactions.
    0 讨论(0)
  • 2020-12-08 07:29

    Generally, you would make use of structures over classes when the data you are defining is relatively simple, you don’t need to worry about referencing, or you don’t need to inherit another data structure’s properties and methods.

    If you have data that should not be changed after initialization we can ensure that at compile time when using structs.

    Use classes for situations where you know that the identity of the object is going to be important. In other words, use classes where you want multiple regions of code to be pointing at the very same instance of the the object.

    Use structs for situations where you know that the value of the object matters. In other words, structs are great for situations where it doesn’t matter if two different regions of code are referring to the very same instance of to copy of the instance

    If you need to share mutable state between parts of you program you should use a class.

    If you need inheritance or you know you want to pass references to an object around, use a class.

    0 讨论(0)
  • 2020-12-08 07:31

    The most important difference between classes and other named types (structs/enums) is:

    Structs cannot be subclasses (or substructs, so to speak) of anything. Nor can they be subclassed themselves. Inheritance is completely out of picture with structs. Same goes for enums.

    0 讨论(0)
  • 2020-12-08 07:39

    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/ffffd-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.

    0 讨论(0)
  • 2020-12-08 07:40

    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

    0 讨论(0)
提交回复
热议问题