Swift Initialize Struct with optional stored properties
hope this could help you
struct Business {
let name : String
var web : String?
var address: String?
// you also need use question mark in init progress
init(name: String, web: String?, address: String?) {
self.name = name
self.web = web
self.address = address
}
}
Once you create a object you could use nil on your optional value For example :
var newBusiness = Business(name: "AWS", web: nil, address: nil)
One approach that you can borrow from other OOP languages is parameter builder pattern. Start with a static method that returns a builder, then add methods for individual parameters, and finally call build()
:
let bakery = Business
.withName("Black Forest")
.andWebSite("www.blackforest.com")
.andAddress("1 Main St, Springfield, IA 98765")
.build()
Here is a skeletal implementation that enables this kind of an API:
class Business {
// Users never call this init, it's for the builder to use
init(name: String, webSite: String?, address: String?) {
...
}
// Here is the method the users call:
static func withName(name: String) {
return BusinessBuilder(name)
}
// This class collects parameters before calling init
class BusinessBuilder {
var name : String
var webSite : String?
var address: String?
func andAddress(address: String) -> BusinessBuilder {
self.address = address
return self
}
func andWebSite(webSite: String) -> BusinessBuilder {
self.webSite = webSite
return self
}
func build() -> Business {
return Business(name, webSite, address)
}
init(name: String) {
self.name = name
}
}
}
This lets you pass as few or as many initializer parameters as you see fit, in any order that you find convenient in a given situation.
The main use of this approach is when you do not know which parameters you are going to get, for example, when they come from an XML or a database. You can call andXyz
methods in a loop, and then call build()
when you have no other attributes to set.
Use default values:
init(busName: String, website: String? = nil, address: String? = nil) {
self.name = busName
self.web = website
self.address = address
}
Then you can call the init like this:
_ = Business(busName: "Foo")
_ = Business(busName: "Foo", website: "www.foo.bar")
_ = Business(busName: "Foo", address: "bar")
_ = Business(busName: "Foo", website: "www.foo.bar", address: "bar")