【问题标题】:Swift extends determined generics type without using objc bindingsSwift 扩展确定的泛型类型而不使用 objc 绑定
【发布时间】:2014-07-14 08:40:16
【问题描述】:

我想尝试用纯 swift 实现消息包。在我来到 Array 之前,一切都很顺利。

我的方法是实现一个名为MsgPackMarshable 的协议,这是扩展的原始类型:

 //Protocol
 protocol MsgPackMarshable{

    func msgpack_marshal() -> Array<Byte>
}

//Implementation for some types
extension UInt8 : MsgPackMarshable{
    func msgpack_marshal() -> Array<Byte>{

        return [0xcc, self]
    }
}

extension UInt16 : MsgPackMarshable{
    func msgpack_marshal() -> Array<Byte>{

        let bigEndian: UInt16 = self.bigEndian
        return [0xcd, Byte((bigEndian & 0xFF00) >> 8), Byte(bigEndian & 0x00FF)]
    }
}

extension UInt32 : MsgPackMarshable{
    func msgpack_marshal() -> Array<Byte>{

        let bigEndian: UInt32 = self.bigEndian
        return [0xce, Byte((bigEndian & 0xFF000000) >> 24), Byte((bigEndian & 0xFF0000) >> 16), Byte((bigEndian & 0xFF00) >> 8), Byte(bigEndian & 0x00FF)]
    }
}

我在扩展Array 时遇到了一些麻烦。我想动态验证数组的类型是否实现了MsgPackMarshable 协议:

extension Array: MsgPackMarshable{
    func msgpack_marshal() -> Array<Byte>{

        for item in self{

           //How to check type here?
        }
                    return []
    }
}

由于Array 是swift 中的结构,我想避免重新定义嵌入数组的新类型Array&lt;MsgPackMarshable&gt;

【问题讨论】:

  • 与您的阵列问题无关,但请注意,对于 UInt16/32,您必须右移 8、16 或 24,而不是 2、3 或 4。
  • 我太笨了 :) 谢谢!

标签: arrays generics dictionary swift


【解决方案1】:

来自被扩展类型(即Array)的类型参数T 在范围内,可用于确定类型。使用the is operator 进行类型检查(T is yourtype)。

【讨论】:

  • 我不允许在非 @objc 协议上使用 is 运算符。错误是:无法从“T”向下转换为非@objc 协议类型“MsgPackMarshable”
  • 很奇怪。如果不创建具有额外约束的函数,其中 T 受限于附加协议,我找不到任何直接与此相关的内容。也许你可以使用MsgPackMarshable 协议。
  • “也许你可以使用 MsgPackMarshable 协议”是什么意思?
  • 您已经使各种对象符合MsgPackMarshable 协议。如果您在函数 (&lt;T: MsgPackMarshable&gt;) 上使用 type constraint 来表示 T 必须符合该协议,那么您知道所有项目都符合 MsgPackMarshable 并且您可以在 for 循环中使用这些方法。它不能帮助您准确了解哪种类型,但您可以调用方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
相关资源
最近更新 更多