【问题标题】:Dynamic generic parameters that return generic type in closure?在闭包中返回泛型类型的动态泛型参数?
【发布时间】:2016-04-12 14:25:53
【问题描述】:

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

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

我从this amazing article 那里得到了一些好主意,所以这就是我试图实现上述目标的目的:

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
    }
}

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

【问题讨论】:

    标签: swift generics swift2 swift2.2


    【解决方案1】:

    您可以在 oder 中使用泛型参数来获取 service 的值类型。为了静态使用它,我建议使用PeripheralKey&lt;T&gt; 而不是它的子类:

    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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 2020-10-26
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      相关资源
      最近更新 更多