我有一个自定义数据结构,我希望能够以通用方式使用它。具体来说,我想传递一个 getter 作为参数,这样我就可以在数字属性上运行特定的函数。这是我遵循的基本模式(玩具问题):
/** A getter for a numeric property of a generic type. */
func genericGet<E, T where T: NumberConvertible>(object: E, getter: E -> T) -> T {
return getter(object)
}
struct EV : Linkable, Equatable, Comparable {
var pitch: Int
var ts: Double
var dur: Double
}
let anEvent = EV(pitch: 61, ts: 2.55, dur: 1.0)
func getSomethingFromSomething<E, T: NumberConvertible>(thing: E, getThing: E -> T) -> T {
return myGet(thing, getter: getThing)
}
let somePitch = getSomethingFromSomething(anEvent, getThing: {$0.pitch})
print("pitch = \(somePitch)") // prints "61"
太棒了!但是,当我在我的通用结构中尝试相同的方法时:
struct MultiLink<E where E: Linkable, E: Equatable, E: Comparable> {
var item: E
var linkedItems: [E]?
func bestTransition<E, T: NumberConvertible>(getter: E -> T, scaling: Double) -> E? {
if let items = linkedItems {
let c = items.count
for i in 0..<c {
let linkedItem = items[i]
let itemProp = genericGet(item, getter: getter) // <--- sadness!
/** Yes, this is unfinished... */
}
}
return nil
}
init(item: E, linkedItems: [E]?) {
self.item = item
self.linkedItems = linkedItems
}
}
编译器提示:
Spliqs.playground:86:57: error: cannot convert value of type 'E -> T' to expected argument type '_ -> _'
let itemProp = genericGet(item, getter: getter)
认为我可能只是将“ setter/getter ”传递给另一个“ setter/getter ”而过火了,我也尝试过:
let itemProp = getter(item)
似乎是合理的(因为 E -> T 是一个 getter 签名),但我得到了一个奇怪的错误:
Playground execution failed: Spliqs.playground:70:32: error: cannot invoke 'getter' with an argument list of type '(E)'
let itemProp = getter(item)
^
Spliqs.playground:70:32: note: expected an argument list of type '(E)'
let itemProp = getter(item)
我说“奇怪”是因为它告诉我它如何“不能”调用 getter,然后还告诉我我需要以完全相同的方式调用它(???)。我是不是在做一些我没看到的蠢事?
最佳答案
Apple 开发论坛上的 Quincey Morris 发现了这个问题。通过在 bestTransition 函数上再次指定 E,我有效地创建了另一个 E。这就是产生令人困惑的错误的原因。删除它使发布的代码工作。
关于swift - 在 Swift 中将 getter 作为函数参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36921840/