Reputation: 1472
Say I have a Swift struct
setup like this :
struct User {
// Properties
var name: String?
var username: String!
var email: String?
}
Now, the way I look at it, there are 2 ways of designing the initializer.
Here's the first:
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.username = username
self.name = name
}
init(username: String, name: String, email: String) {
self.username = username
self.name = name
self.email = email
}
Here's the second :
init(username: String) {
self.username = username
}
init(username: String, name: String) {
self.init(username: username)
self.name = name
}
init(username: String, name: String, email: String) {
self.init(username: username, name: name)
self.email = email
}
Which is the better practice and does it even make a difference ?
Upvotes: 2
Views: 786
Reputation: 285290
Actually you need only one initializer at all.
username
seems to be required, so declare it as non-optional.
If you provide a default value for the other parameters they could be omitted.
struct User {
// Properties
var name: String?
var username : String
var email: String?
init(username: String, name: String? = nil, email: String? = nil) {
self.username = username
self.name = name
self.email = email
}
}
Now you can use these three forms with one initializer
User(username: "Foo")
User(username: "Foo", name: "Bar")
User(username: "Foo", name: "Bar", email:"john@doe.com")
In this case I'd recommend to declare all properties as non-optionals. The absence of a value can be represented with an empty string and you have never to deal with optional bindings or forced unwrapping.
struct User {
// Properties
var name, username, email : String
init(username: String, name: String = "", email: String = "") {
...
The behavior of the initializer is exactly the same
Upvotes: 11
Reputation: 3464
This is not correct. Based on Apple Documentation, if you want to make multiple initializer that does the same thing you could use convenience initializer like this. Convenience initializer will finally call the designated initializer.
convenience init(username: String?) {
self.init(username: username, name: nil)
}
convenience init(username: String?, name: String?) {
self.init(username: username, name: name, email: nil)
}
// designated initializer
init(username: String?, name: String?, email: String?) {
self.init(username: username, name: name)
self.email = email
}
Now you can call it like this
let user = User(username: "john")
or
let user = User(username: "john", name: "John Doe")
or
let user = User(username: "john", name: "John Doe", email: "johndoe@domain.com")
Upvotes: 1