【问题标题】:Getting static variables from a string从字符串中获取静态变量
【发布时间】:2018-09-03 09:29:57
【问题描述】:

我有以下描述国家/地区的类:

class Country: NSObject {

    public var name: String

    static let england = Country(name: "England")
    static let scotland = Country(name: "Scotland")
    static let allCountries = [england, scotland]

    init(name: String) {
        self.name = name
        super.init()
    }

    convenience init?(named name: String) {
        guard let country = Country.allCountries.filter( { $0.name == name } ).first else { return nil }
        self.init(name: country.name)
    }

}

要获得常量Country.england,我会使用:

let england = Country.england

但是,我希望能够使用 convenience init?(named name: String)String 获取此常量,如下所示:

let england = Country(named: "England")

这似乎有点笨拙,这段代码初始化了一个新的“england”实例,而不是采用静态实例。

是否有更快捷的方式来执行此操作? 理想情况下,我只想让 self = countryconvenience init?(named name: String) 函数中,但我收到错误 cannot assign to value : 'self' 是不可变的

感谢您的帮助。

【问题讨论】:

  • 带有文字字符串的 KVC 根本不是 Swifty ????.
  • 专业提示 - 使用 .first(where: { $0.name == name } ) 而不是 .filter( { $0.name == name } ).first
  • @AshleyMills 感谢您的提示
  • @vadian touché ;-)

标签: ios swift string static initialization


【解决方案1】:

如果你的Country 只有一个name,那么你最好使用枚举......

enum Country: String, CaseIterable {
    case england = "England"
    case scotland = "Scotland"
}

Country(rawValue: "Scotland") // Optional(scotland)
Country(rawValue: "Wales")    // nil

注意CaseIterable 是 Swift 4.2+,但允许你写 Country.allCases

Country.allCases  // [england, scotland]

【讨论】:

  • 感谢您的建议。原始帖子更像是一个最小的工作示例。这个类比只有一个变量更复杂。
【解决方案2】:

改用named 工厂方法怎么样?

static func named(_ name: String) -> Country? {
    return Country.allCountries.first(where: { $0.name == name } )
}

// usage:
let england = Country.named("England")!

如果Country 是一个结构,则可以使用初始化方法:

struct Country {

    public var name: String

    static let england = Country(name: "England")
    static let scotland = Country(name: "Scotland")
    static let allCountries = [england, scotland]

    init(name: String) {
        self.name = name
    }

    init?(named name: String) {
        guard let country = Country.allCountries.filter( { $0.name == name } ).first else { return nil }
        self = country
    }

}

【讨论】:

  • 谢谢,我倾向于这是更好的方法,但在我看来,初始化它而不是调用类函数会更好......
  • @AlexJ.R.Lewis 如果Country 是一个结构,你可以使用初始化器。查看编辑。
  • 那是我的下一个问题——它是否需要从NSObject 继承,是否需要是一个`class?
  • @AshleyMills 我会研究结构。也许它不需要从NSObject 继承。 Country 只需要是平等的并且有一堆 UI* 对象。
猜你喜欢
  • 2022-10-21
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 2011-03-09
  • 2019-01-31
  • 2011-08-21
相关资源
最近更新 更多