(对应swift版本3.1)
Swift里面提供了两种对Data范围截取的方法:
一种是subdata()
另一种是下标取值
同学们先来思考下面一段代码
let array:[UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06]
let data = Data(bytes: array)
//问题:请问以下六个的结果是?
data.subdata(in: 3...4).forEach{ print("a \($0)") }
data.subdata(in: 3..<3).forEach{ print("b \($0)") }
data.subdata(in: 3..<4).forEach{ print("c \($0)") }
data[3...4].forEach{ print("A \($0)") }
data[3..<3].forEach{ print("B \($0)") }
data[3..<4].forEach{ print("C \($0)") }
结果是:
data.subdata(in: 3...4).forEach{ print("a \($0)") } //报错
data.subdata(in: 3..<3).forEach{ print("b \($0)") } //0 bytes
data.subdata(in: 3..<4).forEach{ print("c \($0)") } //0x04
data[3...4].forEach{ print("A \($0)") } //0x04, 0x05
data[3..<3].forEach{ print("B \($0)") } //0 bytes
data[3..<4].forEach{ print("C \($0)") } //0x04
为什么 data.subdata(in: 3...4) 会报错呢?
再来看多次Swift.Data关于subdata()的定义:
此方法要求的传值为Range<Data.Index> (Data.Index其实就是Int)
而 3...4 实际上是CountableClosedRange
我们知道,Swift3.0以后,Range有四种:
而这四种Range并不能在互相之间直接转换
因此 data.subdata(in: 3...4) 就会报上述错误
那么为什么下标取值既能用CountableClosedRange,也能用CountableRange?
翻阅Swift源代码就知道原因
....因为Swift对四种Range都定义了下标取值
下面来做点优化:对Data进行扩展
extension Data
{
public func subdata(in range: CountableClosedRange<Data.Index>) -> Data
{
return self.subdata(in: range.lowerBound..<range.upperBound + 1)
}
}
再来运行
let array:[UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06]
let data = Data(bytes: array)
data.subdata(in: 3...4).forEach{ print("a \($0)") }
//a 4
//a 5
完。