Hi all,
in most object-oriented languagues (such as Java and C++), it is considered a good practice to keep internal attributes private and, when in need to access or change it, create a get and set method like in the examble below:
class Person {
private String name;
public String getName () {
return this.name;
}
public void setName (String newName) {
this.name = newName;
}
}However, with what I've seen in Swift, it is possible to do the same in different ways:
1 - like the case before:
class Person {
private var name: String
func getName () -> String {
return name
}
func setName (_ newName: String) {
name = newName
}
}2 - using computed properties:
class Person {
private var _name: String
var name: String {
get {
return _name
}
set {
_name = newValue
}
}
}3 - using different access control levels for the variable (in case you won't need a public set method):
class Person {
private(set) var name: String
}I'd like to know if is there a convention in the Swift community for which of the three is most accepted. I looked a little online, but I had no success.
Thanks
Neither #1 or #2 is idiomatic for Swift on Apple platforms.
Keep in mind that there are no instance variables exposed in Swift at the syntactic level. That is, this:
private var _name: Stringis still a Swift property. Backing storage for a property (aka "instance variable" in other languages) is implicit. That means your #2 just uses two properties to do exactly the same thing as one property. (Well, it's slightly worse, because doing it that way may prevent optimizations such as inlining.)
The only use scenario for something like #2 would be if the getter or setter had additional logic that required a computed property. In that case, you might use a second, private property to provide the backing store.
In the original Obj-C language, there was no property syntax (dot syntax), so properties had to accessed via explicit methods along the lines of your #1. (But Apple doesn't use "get" in the getter name like this. The getter would have been called just "name" and the instance variable would have been "_name".) There are some Obj-C holdouts who hate the property syntax introduce in Obj-C 2.0 and continue to use explicit accessor methods, but Swift is fully committed to property syntax.
The only use scenario for something like #1 would be to add functionality not supported by property syntax: for example, if you wanted to have an "animated: Bool" parameter on the setter, as happens in a couple of places in the Cocoa SDK, or if you wanted the getter or setter to be able to throw errors. (The ability to throw from property accessors may well be coming in a future version of Swift. I believe the ability to add parameterized behavior to properties has been discussed in the past, and is sort of on the radar for future consideration. As KMT says, you'd need to go over to swift.org to get into this.)
The getName/setName thing is really just a left-over mannerism from the bad old days, when developers were still unfamiliar with the idea of property accessors, and the language (Java) wasn't really in a position to absorb the needed syntax changes to do it properly.