2016-11-04 9 views
6

W Swift 3, zastanawiam się, dlaczego jestem w stanie użyć operatora o połowie otwartego zakresu ..< w Data.subdata(in:), ale nie operatora o zamkniętym zasięgu ....Korzystanie z operatora Range w Data.subdata

Szukałem wszędzie, ale nie mogę zrozumieć, dlaczego to daje mi ten błąd: Nie „...” kandydaci produkować oczekiwany kontekstowe typ wyniku «Zakres» (aka «Zakres»)

Oto przykład zarówno jeden, który działa i nie robi:

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 

Dzięki!

+0

Twój komentarz doprowadziły mnie do nowego wyszukiwania i teraz rozumiem, po przeczytaniu tego: https://oleb.net/blog/2016/09/swift- 3 zakresy /. Jeśli chcesz napisać odpowiedź, chętnie ją zaakceptuję. W Swift wciąż jestem trochę zielony, więc ci nie wyskakują na mnie jak na oczy! Nie zdawałem sobie sprawy, że obaj operatorzy zwrócili różne rodzaje "zakresów". – droussel

+0

Dodałem odpowiedź :) – Hamish

Odpowiedz

8
  • ..< jest półotwarterange operator, która może tworzyć zarówno Range lub CountableRange (w zależności od tego, czy jest StrideableBound z IntegerStride lub nie). Utworzony zakres zawiera dolną granicę, ale bez górnej granicy.

  • ... jest zamknięte operator zakresu, który może tworzyć zarówno ClosedRange lub CountableClosedRange (takie same warunki jak opisano powyżej). Zakres, który jest tworzony, obejmuje zarówno górne, jak i dolne granice.

Dlatego jako subdata(in:) oczekuje Range<Int>, nie można korzystać z zamkniętą operator zakresu ... aby skonstruować argument - należy użyć pół-otwartych zakres zamiast operatora.

Byłoby jednak banalnie, aby przedłużyć Data i dodać przeciążenie, które akceptuje ClosedRange<Int>, co pozwoliłoby na użycie operatora o zamkniętym zakresie.

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} 
+0

Świetnie! I dziękuję bardzo za szczegółową odpowiedź, która zawiera rozszerzenie! – droussel

+0

@droussel Z przyjemnością pomogę :) – Hamish

0
import Foundation 

let x = Data(bytes: [0x0, 0x1]) 
let y : UInt8 = x.subdata(in: Range(0..<2)).withUnsafeBytes{$0.pointee} 
let z : UInt8 = x.subdata(in: Range(0...1)).withUnsafeBytes{$0.pointee} 
+3

Odpowiedzi tylko na kod nie są zbyt przydatne dla osób szukających podobnych problemów. Dodaj uwagi, aby opisać, dlaczego ten kod odpowiada na pytanie i co dodaje ponad i tak już zaakceptowaną odpowiedź. –

Powiązane problemy