在Swift

时间:2016-01-25 14:04:15

标签: struct swift2

我们说struct中有以下Swift

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

现在我有一个包含数据结构数组的类:

class MyClass {
   var myDataArray: [Data]
}

现在让我们说我想计算旧值或新值的平均值:

func calculateAverage(oldOrNew: String) -> Double {
   var total = 0.0
   count = 0

   for data in myDataArray {
      total += data.oldOrNew
      count++
   }

   return total / Double(count)
}

然后:

let oldAverage = calculateAverage("old")
let newAverage = calculateAverage("new")

但这显然不起作用,因为oldOrNew不是我struct的成员。

如何从oldnew访问"old""new"

3 个答案:

答案 0 :(得分:5)

这个"反射少"溶液

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")
        }
    }
}

现在你可以这样做

let data = Data(old: 0, new: 1)

data.valueByPropertyName("old") // 0
data.valueByPropertyName("new") // 1

答案 1 :(得分:5)

您正在寻找通过密钥(路径)访问属性的键值编码(KVC)。

简短回答struct不支持KVC。

如果您的设计中struct不是必需的,请使用NSObject的子类,您可以免费获得KVC甚至是@avg等运算符。

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")

编辑:在Swift 4中,struct确实支持Swift KVC,但运算符@avg不可用

答案 2 :(得分:0)

你不会在Swift中按名称访问struct属性,就像在C ++中一样。你提供一个区块。

临时的:

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

...

calculateAverage({$0.old})
calculateAverage({$0.new})

可能average {$0.old}是一种更自然的语法 - 动词并不真正有用,如果你断言它是什么,而不是计算机应该做什么,那么省略括号看起来很好。