Struct vs Class

289 阅读3分钟

Structure is much more faster than Class. Also, if you need inheritance then you must use Class. Most important point is that Class is reference type whereas Structure is value type. 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. If you can always send a copy of your variable to other places, you never have to worry about that other place changing the value of your variable underneath you.

With Structs, there is much less need to worry about memory leaks or multiple threads racing to access/modify a single instance of a variable. (For the more technically minded, the exception to that is when capturing a struct inside a closure because then it is actually capturing a reference to the instance unless you explicitly mark it to be copied).

Classes can also become bloated because a class can only inherit from a single superclass. That encourages us to create huge superclasses that encompass many different abilities that are only loosely related. Using protocols, especially with protocol extensions where you can provide implementations to protocols, allows you to eliminate the need for classes to achieve this sort of behavior(Even in the topic of inheritance, struct with protocols are better than huge one-only inherited classes).

Why struct?

  1. Value type instances are safe in a multi-threaded environment as multiple threads can mutate the instance without having to worry about the race conditions or deadlocks
  2. Value type has no references unlike reference type; therefore there is no memory leaks.
  3. automatically threadsafe due to not being shareable
  4. uses less memory due to no isa and refcount (and in fact is stack allocated generally)
  • methods are always statically dispatched, so can be inlined (though @final can do this for classes)
  • The structure's primary purpose is to encapsulate a few relatively simple data values.
  • It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
  • Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
  • The structure does not need to inherit properties or behavior from another existing type.

Examples of good candidates for structures include:

  • The size of a geometric shape, perhaps encapsulating a width property and a height property, both of type Double.
  • A way to refer to ranges within a series, perhaps encapsulating a start property and a length property, both of type Int.
  • A point in a 3D coordinate system, perhaps encapsulating x, y and z properties, each of type Double.

Why class?

It should be always a fallback unless these cases:

  • Copying or comparing instances doesn't make sense (e.g., Window)
  • Instance lifetime is tied to external effects (e.g., TemporaryFile)
  • Instances are just "sinks"--write-only conduits to external state (e.g.CGContext)

Structs are value type and Classes are reference type

Use a value type [e.g. struct, enum] when:

  1. Comparing instance data with == makes sense
  2. You want copies to have independent state
  3. The data will be used in code across multiple threads

Use a reference type [e.g. class] when:

  1. Comparing instance identity with === makes sense
  2. You want to create shared, mutable state

To extend knowledge:

Value types:

  • Struct
  • Enum
  • Tuple
  • Primitives (Int, Double, Bool etc.)
  • Collections (Array, String, Dictionary, Set)

Reference types:

  • Class
  • Anything coming from NSObject
  • Function
  • Closure

Little grammer advantage

  • structs get an automatic initializer that you don't have to maintain in code at all
  • To get this in a class, you would have to add the initializer, and maintain the intializer...

In terms of var and let

struct Point{

   var x = 0.0;
   var y = 0.0;

} 

Defines a struct called Point.

var point = Point(x:0.0,y:2.0)

Now if I try to change the x. Its a valid expression.

point.x = 5

But if I defined a point as constant.

let point = Point(x:0.0,y:2.0)
point.x = 5 //This will give compile time error.
In this case entire point is immutable constant.

If I used a class Point instead this is a valid expression. Because in a class immutable constant is the reference to the class itself not its instance variables (Unless those variables defined as constants)

To sum up(my get):

  • Thead safe(no shareable, so no race condition, no deadlocks)
  • No memory leak(no reference)
  • Less memory(no isa and refcount,stack allocated)
  • faster execution time
  • inheritance even better with protocol (multiple inheritance rather than single inherit in class)
  • automatic initializer(no init code like class)

vs

  • shared, mutable state(useful when too large to copy very frequently)
  • Can't copy or comparing(Window)
  • instance lifetime tied to external effect(Temporary File)
  • instance one-way causing the external state(CGContext)

It implies that structs should be the default and classes should be a fallback. So always consider struct first!

Reference: stackoverflow.com/questions/2…