1

我正在尝试为复杂的场景实现一个简单的 API。我有一种异步检索数据的类型(实际上是蓝牙设备)。所以我试图最终得到的 API 是这样的:

peripheral.requestData(.Temperature) { value: Double in
    print(value)
}

我从这篇了不起的文章中得到了一些好主意,所以这就是我试图实现上述目标的目的:

class MyPeripheral {

    class Keys {
        static let Temperature = PeripheralKey<Double>("Temperature")
        static let UserData = PeripheralKey<[String: String]>("UserData")
    }

    func requestData(service: Keys, handler: (value: ???Get ValueType from PeripheralKey???) -> Void) {
        if let service = service as? PeripheralKey<Int> {
            service.key //Do something
        } else if let service = service as? PeripheralKey<[String: String]>
            //Do something else
        }
    }
}

class PeripheralKey<ValueType>: MyPeripheral.Keys {
    let key: String

    init(_ key: String) {
        self.key = key
    }
}

我遇到了返回的闭包类型的问题。我想根据传入的外围泛型类型键进行强类型化,但无法掌握如何做到这一点,或者可能需要不同的方法?任何帮助或方向将不胜感激!

4

1 回答 1

2

您可以在 oder 中使用泛型参数来获取service. 为了静态使用它,我建议使用PeripheralKey<T>而不是它的子类:

class MyPeripheral {

    class Keys {
        static let Temperature = PeripheralKey<Double>("Temperature")
        static let UserData = PeripheralKey<[String: String]>("UserData")
    }

    // use a generic parameter T
    func requestData<T>(service: PeripheralKey<T>, handler: (value: T) -> Void) {
        // if you do similar things like in your posted link
        // you can use ("data" has to be defined by you):
        // data[service.key] as! T
    }
}

// make class final as long as you don't subclass it
final class PeripheralKey<ValueType>: MyPeripheral.Keys {
    let key: String

    init(_ key: String) {
        self.key = key
    }
}

let peripheral = MyPeripheral()
// here you can omit the explicit Double declaration
peripheral.requestData(.Temperature) { value in
    print(value)
}

在 Swift 3.0 发布后,您可以将静态属性放在泛型类型中,这样您就可以只使用一个这样的结构:

struct PeripheralKey<ValueType> {

    static let Temperature = PeripheralKey<Double>("Temperature")
    static let UserData = PeripheralKey<[String: String]>("UserData")

    let key: String

    init(_ key: String) {
        self.key = key
    }
}
于 2016-04-12T17:58:55.923 回答