繁体   English   中英

Swift 使用可选的存储属性初始化结构

[英]Swift Initialize Struct with optional stored properties

我是 Swift 新手,我正在尝试使用带有可选属性的结构体。 我已经做了很多搜索并得到了一些有用的东西,但感觉效率非常低,所以想知道是否有更好/更易于管理的方法来实现我的目标。

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

您可以从其他 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)   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM