3 ms·
I wonder why Swift went with the approach of struct is a value type and class is a reference type. This approach means that when I am defining my type, I have t
by ankurdhama 3y ago
I wonder why Swift went with the approach of struct is a value type and class is a reference type. This approach means that when I am defining my type, I have to decide whether it will be used as value type or reference type whereas in C++ same type can be used as reference type (pass by reference) or value type (pass by value) in different situations.
- chromatin 3y agoThis is exactly the approach taken by Walter Bright in Dlang, IIRC. https://dlang.org/spec/struct.html https://dlang.org/spec/struct.html
- mrtksn 3y agoI only guess but maybe because in Swift they encourage you to use value types whenever possible, so you have to make a conscious decision when you are steering away from the default. This way it emphasises a particular way of reasoning about the code. Also, it's pretty straightforward to create a reference type of a value type if you end up need it: Just create a new type that is a reference type and has the value type as a property. No?
- dwaite 3y agoGenerally you don't use reference types until you encounter a need for something to be a reference type, such as being a reference to a particular resource, or for usage compatibility with an external system. For example, there are something like eight classes exposed in the minimal swift standard library, representing concepts like managed buffers, singletons like the MainActor, and for implementing concepts like task-local values. These are all examples of types which do not lend themselves to being value types. Once you start getting to file and network I/O, or interfacing with Objective-C, you start to see the percentage of reference types climb.
- cageface 3y agoUnfortunately the new Observation framework in SwiftUI currently forces you to use classes to model your data. Hopefully they can find some way to make it work with value types.
- pjmlp 3y agoIt follows up other languages with automatic resource management that have taken similar design decisions.
- TillE 3y agoYeah it's very similar to C#, and in both languages you can pass structs by reference using the appropriate keyword.
- jb1991 3y agoDon’t forget that behind the scenes a value type might actually be used as a reference type when the code is compiled, for performance reasons, but conceptually the language encourages you to think of everything as value types when possible. A big part of the semantics in the language is “copy on write”.
- GRiMe2D 3y agoSwift actually passes value types by reference on closures (anonymous functions) if they aren't explicitly listed in capture group. It's per spec. It allows you to write closures with states: var count = 0 let closure = { count += 1 print("Current count=", count) } closure() // Current count= 1 closure() // Current count= 2 closure() // Current count= 3 let capturedVariableClosure = { [count] in print("Current count=", count) //count += 1 // syntax error, count is const variable. Use var count in capture group } capturedVariableCount() // Current count= 3 closure() // Current count= 4 capturedVariableCount() // Current count= 3
- jb1991 3y agoI think you meant to call your second closure `capturedVariableCount`
- fauigerzigerk 3y agoProbably because it causes the least "noisy" syntax. But I think it's a mistake. A language that lets you freely choose between using values and references should make it very clear at the call site which one is being used. This one "feature" has caused more bugs in my Swift code than anything else. For frequently used types I can remember whether they are structs or classes. But for new code written by others or my own code when the design isn't quite settled yet, I need every syntactical clue I can get to avoid mistakes. This is not the only place where Swift goes with "clean" syntax at the expense of local clues that help readability. Result builders are another example.