(对应swift版本3.1)
Swift里面提供了两种对Data范围截取的方法:
一种是subdata()
![](https://img.haomeiwen.com/i1972693/99a45fa5b0fc0ed1.png)
另一种是下标取值
![](https://img.haomeiwen.com/i1972693/5f4b05332aa5830e.png)
同学们先来思考下面一段代码
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
![](https://img.haomeiwen.com/i1972693/7410d928b5c63b53.png)
为什么 data.subdata(in: 3...4) 会报错呢?
再来看多次Swift.Data关于subdata()的定义:
![](https://img.haomeiwen.com/i1972693/92f35af249a7047d.png)
此方法要求的传值为Range<Data.Index> (Data.Index其实就是Int)
而 3...4 实际上是CountableClosedRange
![](https://img.haomeiwen.com/i1972693/8551d6993a877ac5.png)
我们知道,Swift3.0以后,Range有四种:
![](https://img.haomeiwen.com/i1972693/2b856d8f925fc5a4.png)
而这四种Range并不能在互相之间直接转换
因此 data.subdata(in: 3...4) 就会报上述错误
那么为什么下标取值既能用CountableClosedRange,也能用CountableRange?
翻阅Swift源代码就知道原因
![](https://img.haomeiwen.com/i1972693/c762f008bb465eba.png)
....因为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
完。
网友评论