Swift用可选的存储属性初始化Struct

我是一个Swift新手,我试图让我的头在使用具有可选属性的Structs。 我做了很多search,find了一些可行的方法,但是效率却非常低,所以我想知道是否有更好的/更易于pipe理的方式来实现我的目标。

我想用Structs来代表一个企业,但我不知道哪个特定业务可能具有哪些特性的组合。 这似乎意味着我必须为每个可能的参数组合创build一个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") 

有没有办法创build一些types的参数是可选的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") 

您可以从其他OOP语言借用的一种方法是参数构build器模式。 从一个返回构build器的静态方法开始,然后为各个参数添加方法,最后调用build()

 let bakery = Business .withName("Black Forest") .andWebSite("www.blackforest.com") .andAddress("1 Main St, Springfield, IA 98765") .build() 

这是一个骨架的实现,使这种types的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 } } } 

这使您可以按照您认为合适的方式传递尽可能less的或尽可能多的初始化参数,以您在特定情况下find的任何顺序进行操作。

这种方法的主要用途是当你不知道你将得到哪些参数,例如,当它们来自XML或数据库时。 您可以在循环中调用andXyz方法,然后在没有其他属性设置时调用build()