jindulys
(Yansong Li)
February 24, 2018, 2:54am
1
When I try to use LazySplitCollection
shown by Swift.org 's blog.(Swift.org - Conditional Conformance in the Standard Library )
subscript(i: Index) -> Element {
let separator = base[i...].index(where: isSeparator)
return base[i..<(separator ?? endIndex)]
}
I can get a compiler error "Incorrect argument label in call (have 'where:', expected 'after:')" for base[i...]
.
I am really confused, to me this seems correct.
Also this is terrible that code in Swift org blog can't compile.
xwu
(Xiaodi Wu)
February 24, 2018, 3:44am
2
Hi Yansong,
The blog post is about a new feature in Swift 4.1. Therefore, you'll need Swift 4.1 to compile the example. The particular code you point out produces the error you see in Swift 4.0, but it compiles without error in Swift 4.1.
If you are using development toolchains with Xcode 9.2, be aware that Playgrounds continue to use the default toolchain; either compile a regular project or use Xcode 9.3 beta.
jindulys
(Yansong Li)
February 24, 2018, 4:19am
3
Thanks for reply.
struct LazySplitCollection<Base: Collection> {
let base: Base
let isSeparator: (Base.Element) -> Bool
}
extension LazySplitCollection: Collection {
typealias Element = Base.SubSequence
typealias Index = Base.Index
var startIndex: Index { return base.startIndex }
var endIndex: Index { return base.endIndex }
subscript(i: Index) -> Element {
let separator = base.index(where: isSeparator)
return base[i..<(separator ?? endIndex)]
}
func index(after i: Index) -> Index {
let separator = base[i...].index(where: isSeparator)
return separator.map(base.index(after:)) ?? endIndex
}
}
For Swift 4.0
LazySplitCollection
wants to confirm to Collection
. It implements required ones so for others requirements it will use default implementation.
Particularly for SubSequence
,
associatedtype SubSequence : Sequence = Slice<Self> where Self.Element == Self.SubSequence.Element, Self.SubSequence == Self.SubSequence.SubSequence
We will have a default SubSequence, which is a Slice<Self>
.
For Slice
itself, it is a collection
. (Apple Developer Documentation )
extension Collection where Self.SubSequence == Slice<Self> {
public subscript(bounds: Range<Self.Index>) -> Slice<Self> { get }
}
According to above, base[i...] should return a Slice, which is a collection.
In my opinion, base[i...].index(where:) should work.
Please correct me if I said something wrong.
xwu
(Xiaodi Wu)
February 24, 2018, 4:43am
4
The documentation you are viewing is for Swift 4.1, not for Swift 4.0. You can see the changes by choosing "API Changes: Show." Your reasoning is correct for Swift 4.1, and the code you're writing is correct for Swift 4.1.
Nevin
February 24, 2018, 4:46am
5
In Swift 4.0, Collection.SubSequence
is not constrained to conform to Collection
.
You can make your code work in Swift 4.0 by adding “where Base.SubSequence : Collection
” to the declaration of LazySplitCollection
.
1 Like
jindulys
(Yansong Li)
February 24, 2018, 4:49am
7
I see, thanks for Swift 4.0 correction!