Hi developers
When we should use struct and when is better to use class in swift 4 ?
Struct. For most purposes you want structs, classes mainly exist for compatibility with Objective C. classes are also useful if you want to implement copy-on-write things. However 98% of the time you want a struct.
Classes have a bad rep in Swift for being slow (though people are working on improving this) but their main issue is that they have reference semantics, and Swift is a language that’s really oriented towards value semantics. This can make code that uses a lot of classes confusing and hard to understand.
see this thread for more
Thanks🌷
The way I like to think about it is, is this a particular thing that exists, or just a set of related data? Would it be absurd to make copies of it all over the place?
For example, a button is a particular thing on the screen; if you assigned it to another variable, you wouldn’t want to make a second button appear on the screen. So your Button type should be a class. On the other hand, a street address is a piece of data; it makes perfect sense for it to be copied and modified separately. So your StreetAddress type should be a struct.
I'm really no fan of the notion that structs are inherently better than classes, but I'd also recommend to start with struct
.
That way, you will automatically notice when you need a class.
When you start with class
, you will never be forced to switch to a struct
, even if this would be the better choice.
How is this true? How would you share state? I wouldn't want to end up with pointers to structs.
Right, but I wouldn't emphasize this aspect - inheritance for structs could be added at any time (but of course, it would need an endless discussion in advance ;-)
I think you mean value type subtyping
which wouldn't be inheritance as you know it in classes.
No ;-)
struct Person {
var name: String
}
struct Friend: Person {
var nickname: String
var description: String {
return "\(name), aka \(nickname)"
}
}
A good rule of thumb would be to always use struct/enums unless you specifically need a reference type, that is, a type whose instances have an explicit identity in terms of memory representation, and you use typically use them to share mutable state. There is some memory layout concern here: gigantic structs with a lot of class-based properties would probably better represented in memory as classes, but I'm no expert here.
In my experience, in the vast majority of cases where people (not familiar with the matter) use a class, they'd better be using a struct instead. Also, shared mutable state is almost always a bad idea, and should be kept at minimum as a good programming pattern in general, even in languages that only have classes. In my apps I frequently write less than 10 classes in total, but dozens of structs and enums.
Classes have inheritance, of course, but even there, favoring composition over inheritance is frequently better, and there are better ways in Swift to distribute implementations (among types), like protocol extensions.
In addition to what’s been mentioned, classes are necessary for wrapping resources like database connection, file handles, query cursors, etc. You create the resource in a classes initializer and put your clean up code (deallocate memory, close file handles and database connections) in the deinitializer. This pattern is called RAII.
It's just the functional crowd trying to define good Swift again. Classes and structs are both equally important parts of Swift, but the fp crowd hates state.
I wouldn't call them equally important, but yes,
isn't quite the whole story. As the others have mentioned, classes are good when reference semantics (e.g. there's a notion of identity) are needed, while structs are for value (no identity) semantics.
One other difference is that it is possible to expose read-only access to a struct which has mutating methods, but not to a class.
struct Foo {
private(set) var x = 0
mutating func addOne() { x += 1 }
}
class Bar {
private(set) var x = 0
func addOne() { x += 1 }
}
struct FooBar {
private(set) var foo = Foo()
private(set) var bar = Bar()
}
var fooBar = FooBar()
fooBar.foo.addOne() // error: cannot use mutating member on immutable value
fooBar.bar.addOne() // compiles, and modifies fooBar.bar.x
In this example we want people who see a FooBar
to be able to read its contents, but not to modify them. However, since Bar
is a class, there is no way to stop them from calling addOne()
.
In fact, we could even declare fooBar
as a let
constant, *and* FooBar.bar
as a let
constant, and the last line of the example would *still* succeed!
understand that class
es in Swift are basically shared pointers in C++. they can be useful but you should use them about as often as you use them in C++ and no more.
inheritance is not a reason to use a class instead of a struct. while i wouldn’t go as far as to say inheritance is harmful™ the swift paradigm is to use protocols and extensions to acheive polymorphism rather than C++-style inheritance.
The latter is rather arguable. Concerning the former, I see no logic. If you need inheritance, you obviously use a class, not a struct. Do you understand my point?
Hmm. By “need inheritance” I understand “my use case is inside the inheritance featureset, but outside its intersection with the protocols + extensions featureset”
I think if that’s the case, yeah, you’d have to use classes. But I don’t think the intersection is empty either.
I learned to design programs in a fully OOP style course in C#. And we made good programs. My first reflex is still to model things with abstract classes, interfaces and inheritance.
I’m still very much new to the protocol + extensions paradigm. But I’ve seen amazing frameworks in Swift that are entirely designed with it. Therefore I believe when Taylor and others say it’s a powerful paradigm. And maybe the intersection of its featureset with OOP style classes design isn’t so small :)
by all means if you need inheritance use a class. my point is i think classes are overused by developers who are used to thinking in terms of inherent when there are actually alternative and better ways to structure a program
Choosing Between Classes and Structures
You can use both classes and structures to define custom data types to use as the building blocks of your program’s code.
...
Examples of good candidates for structures include:
- The size of a geometric shape, perhaps encapsulating a
width
property and aheight
property, both of typeDouble
. - A way to refer to ranges within a series, perhaps encapsulating a
start
property and alength
property, both of typeInt
. - A point in a 3D coordinate system, perhaps encapsulating
x
,y
andz
properties, each of typeDouble
.
In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures. [emphasis mine]
— The Swift Programming Language (Swift 4.1) by Apple Inc.