Struct and class

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

3 Likes

I just imagined UIKit as a struct based framework...That would be ridiculous.

@TalebRafeipoor keep in mind though you can't inherit from a struct, which is a very straightforward answer to your question, by the way.

1 Like

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.

9 Likes

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.

5 Likes

How is this true? How would you share state? I wouldn't want to end up with pointers to structs.

1 Like

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)"
  }
}

You have a point, but this is a very delicate topic. If structs adopted inheritance, they would cease to be structs. I am not familiar with the manifesto @DevAndArtist linked, but I am confident structure "inheritance" implies either a significantly different inheritance concept that tweaks value type semantics (under the hood) or a new type construct. Either way, the main question of this thread would need a reformulation :)

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.

3 Likes

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.

2 Likes

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.

3 Likes

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.

2 Likes

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!

1 Like

understand that classes 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.

2 Likes

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 :)