Swift:使用字符串访问结构变量

Swift: accessing struct variables with a String

我正在寻找一种访问结构变量的更好方法。 json 查询填充此结构的数组:

    struct AnimalInfo: Codable {
        var English: String
        var French: String
        var Spanish: String
    }

一个例子:

    let theDog = AnimalInfo(English: "Dog", French: "Chien", Spanish: "Perro")

语言在一个数组中,当前的语言总是在变化。我用指针跟踪:

    let languageListArray = ["English", "French", "Spanish"]
    let currentLanguage = languageListArray[2]

我希望能够使用此信息从结构中检索值,大致如下:

    let myString = theDog.currentLanguage // = "Perro"

.. 但当然这是不可能的。到目前为止我想出的最好的是一个开关:

    switch currentLanguage {
        case "English":
            return theDog.English
        case "French":
            return theDog.French
        case "Spanish":
            return theDog.Spanish
    }

但这很丑陋,而且不能很好地适应多种语言!谁有更好的方法?

but of course that is not possible

哦,如果你使用key paths

是可以的
struct AnimalInfo: Codable {
    let english: String
    let french: String
    let spanish: String
}

let theDog = AnimalInfo(english: "Dog", french: "Chien", spanish: "Perro")

let languageListArray : [KeyPath<AnimalInfo,String>] = [\.english, \.french, \.spanish]

let currentLanguage = languageListArray[2]

let myString = theDog[keyPath: currentLanguage] // = "Perro"

没有keyPaths也是可以的

protocol Translated {
    var english: String { get }
    var french: String { get }
    var spanish: String { get }
}

struct Animal: Codable, Translated {
    let english: String
    let french: String
    let spanish: String
}

let english: (Translated) -> String = { [=10=].english }
// or you can write that as a key path \.english 
let french: (Translated) -> String = { [=10=].french }
let spanish: (Translated) -> String = { [=10=].spanish }


let theDog = Animal(english: "Dog", french: "Chien", spanish: "Perro")

english(theDog) // Dog

french(theDog) // Chien

var currentLanguage: (Translated) -> String = english

currentLanguage(theDog) // Dog

currentLanguage = french

currentLanguage(theDog) // Chien

如果您想要点语法,那么:

extension Translated {
    var inCurrentLanguage: String { currentLanguage(self) }
}

theDog.inCurrentLanguage // Chien

您确实可以使用键路径来指定您的函数而无需命名,例如

// no need to define/name these functions
// let spanish: (Translated) -> String = { [=12=].spanish }

currentLanguage = \.spanish

theDog.inCurrentLanguage // Perro