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 ?
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:"[email protected]")
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
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: "[email protected]")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With