在 Swift 3 中,我想知道为什么我能够在
Data.subdata(in:)中使用半开范围运算符
..<
,但不能使用闭范围运算符 ...
。
我到处搜索但不明白为什么它给我这个错误: 没有“...”候选人产生预期的上下文结果类型 “范围”(又名“范围”)
这是一个有效和无效的示例:
import Foundation
let x = Data(bytes: [0x0, 0x1])
let y : UInt8 = x.subdata(in: 0..<2).withUnsafeBytes{$0.pointee}
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes{$0.pointee} // This fails
谢谢!
..<
是 半开 范围运算符,它可以创建 Range
或 CountableRange
(取决于 Bound
是否为 Strideable
) Integer
Stride
与否)。创建的范围包含下限,但不包含上限。...
是close范围运算符,它可以创建ClosedRange
或CountableClosedRange
(与上面的要求相同)。创建的范围包含两者上限和下限。subdata(in:)
需要 Range<Int>
,因此您不能使用闭域运算符 ...
来构造参数 - 您必须使用半开域运算符。
但是,扩展
Data
并添加接受 ClosedRange<Int>
的重载将是微不足道的,这将允许您使用闭范围运算符。
extension Data {
func subdata(in range: ClosedRange<Index>) -> Data {
return subdata(in: range.lowerBound ..< range.upperBound + 1)
}
}
let x = Data(bytes: [0x0, 0x1])
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes {$0.pointee}
冒着我的评论被关闭的风险,无论如何我都会说出来 - 我遵循了关闭/删除评论的建议,因为所选答案不适用于 Swift 5。工作解决方案是:
x.subdata(in: Range(0...1))
我认为这与“Range”与“NSRange”的解释有关 - 但老实说我不知道。
有一个更方便的方法:在数据上使用扩展:
extension Data {
///subscript for use Closed Range
subscript(in closedRange:ClosedRange<Int>) -> Data {
self[index(self.startIndex, offsetBy: closedRange.lowerBound) ... index(self.startIndex, offsetBy: closedRange.upperBound)]
}
///subscript for use Range
subscript(in openRange:Range<Int>) -> Data {
self[index(self.startIndex, offsetBy: openRange.lowerBound) ..< index(self.startIndex, offsetBy: openRange.upperBound)]
}
}