Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of Range operator in Data.subdata

Tags:

swift

In Swift 3, I wonder why I'm able to use the half-open range operator ..< in Data.subdata(in:) but not the closed range operator ....

I've searched everywhere but can't understand why it gives me this error : no '...' candidates produce the expected contextual result type 'Range' (aka 'Range')

Here's an example of both the one that works and the one doesn't :

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

Thanks!

like image 915
droussel Avatar asked Nov 04 '16 20:11

droussel


1 Answers

  • ..< is the half-open range operator, which can either create a Range or CountableRange (depending on whether the Bound is Strideable with an Integer Stride or not). The range that is created is inclusive of the lower bound, but exclusive of the upper bound.

  • ... is the closed range operator, which can either create a ClosedRange or CountableClosedRange (same requirements as above). The range that is created is inclusive of both the upper and lower bounds.

Therefore as subdata(in:) expects a Range<Int>, you cannot use the closed range operator ... in order to construct the argument – you must use the half-open range operator instead.

However, it would be trivial to extend Data and add an overload that does accept a ClosedRange<Int>, which would allow you to use the closed range operator.

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}
like image 171
Hamish Avatar answered Sep 18 '22 16:09

Hamish