Access a struct property by its name as a string in Swift

后端 未结 3 2117
南方客
南方客 2021-02-20 13:28

Let\'s say I have the following struct in Swift:

struct Data {
   let old: Double
   let new: Double
}

Now I have a c

相关标签:
3条回答
  • 2021-02-20 14:11

    What about this "reflection-less" solution?

    struct Data {
        let old: Double
        let new: Double
    
        func valueByPropertyName(name:String) -> Double {
            switch name {
            case "old": return old
            case "new": return new
            default: fatalError("Wrong property name")
            }
        }
    }
    

    Now you can do this

    let data = Data(old: 0, new: 1)
    
    data.valueByPropertyName("old") // 0
    data.valueByPropertyName("new") // 1
    
    0 讨论(0)
  • 2021-02-20 14:14

    You wouldn't access a struct property by name in Swift any more than you would in C++. You'd provide a block.

    Extemporaneous:

    func calculateAverage(getter: (Data) -> Double) {
        ... total += getter(data) ...
    }
    
    ...
    
    calculateAverage({$0.old})
    calculateAverage({$0.new})
    

    Possibly with average {$0.old} being a more natural syntax — the verb isn't really helpful and if you're asserting what it is, not what the computer should do, then omitting the brackets looks fine.

    0 讨论(0)
  • 2021-02-20 14:18

    You're looking for key-value-coding (KVC) that is accessing properties by key (path).

    Short answer: A struct does not support KVC.

    If the struct is not mandatory in your design use a subclass of NSObject there you get KVC and even operators like @avg for free.

    class MyData : NSObject {
      @objc let old, new: Double
    
      init(old:Double, new:Double) {
        self.old = old
        self.new = new
      }
    }
    
    let myDataArray : NSArray = [MyData(old: 1, new: 3), MyData(old:5, new: 9), MyData(old: 12, new: 66)]
    
    let averageOld = myDataArray.value(forKeyPath:"@avg.old")
    let averageNew = myDataArray.value(forKeyPath: "@avg.new")
    

    Edit: In Swift 4 a struct does support Swift KVC but the operator @avg is not available

    0 讨论(0)
提交回复
热议问题