在Swift

时间:2016-04-28 17:40:39

标签: swift generics closures

我有一个自定义数据结构,我希望能够以通用方式使用。具体来说,我想传递一个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)

想到也许我只是通过将“吸气剂”传递给另一个“吸气剂”而过火,我也尝试过:

let itemProp = getter(item)

似乎合理(因为E - &gt; 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)

我说“奇怪”,因为它告诉我它如何“不能”调用吸气剂,然后还告诉我需要以这种方式调用它(???)。我做了一些愚蠢的事情,我只是没有看到?

1 个答案:

答案 0 :(得分:0)

Quincey Morris在Apple开发论坛上发现了这个问题。通过在bestTransition函数上再次指定E,我有效地创建了另一个 E.这就产生了令人困惑的错误。删除使发布的代码有效。