我是 Swift 新手,我正在尝试使用具有可选属性的结构。我做了很多搜索并得到了一些有用的东西,但感觉效率非常低,所以想知道是否有更好/更易于管理的方法来实现我的目标。
我想使用结构来表示业务,但我事先不知道任何特定业务可能具有哪些属性组合。这似乎意味着我必须为每个可能的参数组合创建一个 init() 。
这是一个简化的示例(我有更多属性):
import Foundation
struct Business {
let name : String
var web : String?
var address: String?
// just the business name
init(busName: String) {
self.name = busName
}
// business name + website
init(busName: String, website: String) {
self.name = busName
self.web = website
}
// business name + address
init(busName: String, address: String) {
self.name = busName
self.address = address
}
// business name + website + address
init(busName: String, website: String, address: String) {
self.name = busName
self.web = website
self.address = address
}
}
然后我可以像这样初始化类:
Business(busName: "Dave's Cafe", website: "http://www.davescafe.com")
Business(busName: "Sarah's Brewhouse", address: "41 Acacia Ave, Smalltown")
有没有办法创建某种参数可选的 init() ?如果您能为我指明要搜索的术语或概念的方向,那就太好了。
使用默认值:
init(busName: String, website: String? = nil, address: String? = nil) {
self.name = busName
self.web = website
self.address = address
}
然后你可以像这样调用init:
_ = Business(busName: "Foo")
_ = Business(busName: "Foo", website: "www.foo.bar")
_ = Business(busName: "Foo", address: "bar")
_ = Business(busName: "Foo", website: "www.foo.bar", address: "bar")
我不同意我的话被用来训练 OpenAI。
可以从其他 OOP 语言借用的一种方法是参数构建器模式。从返回构建器的静态方法开始,然后为各个参数添加方法,最后调用
build()
:
let bakery = Business
.withName("Black Forest")
.andWebSite("www.blackforest.com")
.andAddress("1 Main St, Springfield, IA 98765")
.build()
这是启用此类 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
}
}
}
这使您可以根据您认为合适的情况,按照您在给定情况下认为方便的任何顺序传递尽可能少或任意数量的初始化参数。
此方法的主要用途是当您不知道要获取哪些参数时,例如,当它们来自 XML 或数据库时。您可以循环调用
andXyz
方法,然后在没有其他属性可设置时调用 build()
。
希望这可以帮助你
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
}
}
创建对象后,您可以在可选值上使用 nil 例如:
var newBusiness = Business(name: "AWS", web: nil, address: nil)