假设我在
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
的成员。
如何从
old
或 new
访问 "old"
或 "new"
?
这个“无反射”解决方案怎么样?
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
您正在寻找通过键(路径)访问属性的键值编码(KVC)。
简短回答:A
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
不可用
在 Swift 中你不会像在 C++ 中那样通过名称访问结构体属性。你会提供一个块。
即兴:
func calculateAverage(getter: (Data) -> Double) {
... total += getter(data) ...
}
...
calculateAverage({$0.old})
calculateAverage({$0.new})
可能
average {$0.old}
是一种更自然的语法 - 这个动词并没有真正的帮助,如果你断言它是什么,而不是计算机应该做什么,那么省略括号看起来不错。