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

Alb*_*igo 4 swift

我想要做的是通过编写这样的函数来解析(部分)二进制协议(MQTT):

func readString(bytes: Array<UInt8> OR ArraySlice<UInt8>) -> (string: String?, remainingBytes: ArraySlice<UInt8>?)
Run Code Online (Sandbox Code Playgroud)

我知道多态性,但我更喜欢有一个函数。

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

mat*_*att 5

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

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

所以现在就这么说吧,泛型让你这么说:

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

这是一个测试:

let arr = [UInt8(1),UInt8(2),UInt8(3)]
readString(arr) // compiles
readString(arr[1...2]) // compiles
Run Code Online (Sandbox Code Playgroud)

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

readString([1,2,3])
Run Code Online (Sandbox Code Playgroud)

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

readString([-1,2,3])
Run Code Online (Sandbox Code Playgroud)

  • 转换为 Array 的问题在于它可能会为其分配内存,而这正是我试图避免的事情。你提供的正是我正在寻找的答案。 (2认同)