Struct 在Swift中以字符串的形式访问结构属性

Struct 在Swift中以字符串的形式访问结构属性,struct,swift2,Struct,Swift2,假设我在Swift中有以下struct: struct Data { let old: Double let new: Double } 现在我有了一个包含数据结构数组的类: class MyClass { var myDataArray: [Data] } 现在让我们假设我要计算旧值或新值的平均值: func calculateAverage(oldOrNew: String) -> Double { var total = 0.0 count = 0

假设我在
Swift
中有以下
struct

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
的成员

如何从
“旧的”
“新的”
访问
旧的
新的

这个“无反射”解决方案怎么样

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

<>你不会在C++中用名字来访问Stutt属性。你会提供一个街区

即席:

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

...

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

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

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

简短回答:结构不支持KVC

如果
结构
在您的设计中不是强制性的,请使用
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
不可用

属性
oldOrNew
应该包含什么?请提供输入和预期输出的示例。目标是访问
数据。旧的
数据。新的
,但我不知道如何将其传递给我的
func
oldOrNew
不是一个属性,它只是一个占位符。我已经提供了一个例子。让我知道我的答案是否解决了你的问题。是的,这看起来是一个很好的解决方案。或者,我也可以只使用
字典
而不是
结构
?当我使用此代码时,会出现以下编译器错误:
条件绑定的初始值设定项必须具有可选类型,而不是
数据的“Double”
。valueByPropertyName(“old”)
此代码不会编译。请告诉我你对它所做的更改。这是我正在工作的一个更大的游乐场的一部分,我确信错误是由此造成的。等我回到我的Mac电脑后再查。