如何编写接受Array <uint8>或ArraySlice <uint8>的函数?

时间:2015-05-29 21:06:23

标签: swift

我尝试做的是通过编写如下函数来解析(部分)二进制协议(MQTT):

func readString(bytes: Array<UInt8> OR ArraySlice<UInt8>) -> (string: String?, remainingBytes: ArraySlice<UInt8>?)

我知道多态,但我更喜欢有一个功能。

我编写了一个函数(使用泛型),它接受ArrayArraySlice UnsignedIntegerType,但我只想UInt8。这似乎是一件简单的事情,但到目前为止我还没有找到一个好的解决方案......

1 个答案:

答案 0 :(得分:4)

我要做的是,首先,忘记返回类型,并考虑这个函数应该接受什么作为其参数。特别是,考虑一下Array和Slice的共同点,并编写一个通用的指定。它们都是 MutableCollectionType Sliceable 。世界上基本上没有别的东西(没有其他你可能会使用的东西,那就是)。

此外,您希望元素类型为UInt8。

所以现在只说,通用的方式让你说出来:

func readString<T:MutableCollectionType 
    where T:Sliceable, T.Generator.Element == UInt8>(bytes: T) {
        // ...
}

这是一个测试:

let arr = [UInt8(1),UInt8(2),UInt8(3)]
readString(arr) // compiles
readString(arr[1...2]) // compiles

这个公式的一个好处是编译器将测试,如果可以的话,看看你是否使用合法的整数类型进行调用。例如,这会编译,因为所有整数都是小而正的:

readString([1,2,3])

但这甚至无法编译,因为编译器知道负整数不能成为UInt8:

readString([-1,2,3])