0

I wanted to try implementing message pack in pure swift. Everything worked well until I came to Array.

The approach I had was to implement a protocol called MsgPackMarshable thats primitiv types extended :

 //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)]
    }
}

I had some troubles extending Array. I wanted to verify dynamically that the type of the array were implementing the MsgPackMarshable protocol:

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

        for item in self{

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

Due to the fact that Array is a struct in swift, I wanted to avoid redefining a new type of Array<MsgPackMarshable> that embeds an Array.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
yageek
  • 4,115
  • 3
  • 30
  • 48

1 Answers1

0

The type parameter T from the type being extended (ie Array) is in scope and can be used to determine the type. Use the is operator to do type checking (T is yourtype).

Jesper
  • 7,477
  • 4
  • 40
  • 57
  • Hm; [see this question](http://stackoverflow.com/questions/24047164/extension-of-constructed-generic-type-in-swift). – Jesper Jul 14 '14 at 12:10
  • 1
    I'm not allowed to use the `is` operator on a non @objc protocol. The error is : cannot downcast from 'T' to non-@objc protocol type 'MsgPackMarshable' – yageek Jul 14 '14 at 12:39
  • Very weird. I can't find anything that speaks directly to this without making a function that has an extra constraint where T is constrained to an additional protocol. Maybe you could use the `MsgPackMarshable` protocol. – Jesper Jul 14 '14 at 13:22
  • What do you mean by "Maybe you could use the MsgPackMarshable protocol?" – yageek Jul 14 '14 at 13:52
  • You're already making various objects conform to the `MsgPackMarshable` protocol. If you use a [type constraint](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-XID_243) on the function (``) to say that T must conform to that protocol, you know that all the items conform to `MsgPackMarshable` and you have those methods available to you in the for loop. It doesn't help you in knowing exactly which type, but you can call the methods. – Jesper Jul 14 '14 at 13:56
  • That only seems to work if the function is global. I haven't been able to find a syntax that adds constraints to a generic type and says, in effect, this function only exists in the generic if this condition is met. A similar problem arises if you try to implement an extension on Array that adds a `uniqueItems` method, but only on Arrays where T: Comparable. – David Berry Jul 14 '14 at 15:34