Swift: Protocol vs. Struct vs. Class

2019-03-09 10:16发布

问题:

I am starting to learn the Swift language and am having trouble wrapping my head around Protocols, Structs and Classes.

I come from the Android side of programming, so I believe that Swift Protocols are basically Java Interfaces?

What would be proper use cases for each of these?

回答1:

These analogies are not "exactly" correct, but this is the gist of it as I understand it

  1. Yes, Protocols are effectively like interfaces

  2. Classes are classes, like in Java/Android, and pretty much any other language

  3. Structs are like classes, but they are passed by-value (copied) when passing them from one variable/function to another. If you're familiar with C# at all, it's implementation of structs is very similar.

Eg:

class Foo {
   ...
}

let x = Foo()
let z = x 

At this point x and z both refer to the same Object in memory, there is only one Foo object

struct Bar {
   ...
}

let a = Bar()
let b = a 

When assigning b, a is copied (think of basically copying the memory block). At this point, there are two independent Bar objects in memory and modifying one doesn't affect the other.

Why is this useful? Sometimes you don't want a shared reference, but mostly for performance reasons. Because structs don't have to all refer to the same object, they don't have to be allocated on the heap. They can instead often be allocated on the stack, which is much faster. Also arrays of structs can be implemented as one big contiguous block of memory which means it's much friendlier on the CPU cache if you want to iterate through it all.

Swift isn't garbage collected, but for garbage collected languages like C# this can mean the garbage collector doesn't have to deal with a lot of objects that it might otherwise have to. Even in swift the struct copying means it can avoid doing the Retain/Release behind the scenes neccessary for ARC, which can help a lot.

The primary use case for structs is when you have lots of immutable "simple data" like a Vector (set of 3 floating point values)