Oliver Borchert Oliver Borchert - 1 year ago 309
Swift Question

Swift 3 Ranges: Best Practices

I downloaded the Xcode 8.0 beta yesterday and consequently Swift 3. The first thing I did was trying to update my project for Swift 3 and I nearly cried. One of the gravest changes is (in my opinion) the new management of Swifts

struct, especially because the automatic conversion to the current Swift syntax does not do anything with the ranges.

is split into
which does make sense when considering what is now possible when using ranges (though it's mostly fairly unnecessary).

However: I have lots of functions accepting a
as parameter or returning a
. The problem is: I called these functions by
for example or
(because it's semantically more expressive sometimes). Of course, I could simply adjust these type of things. But why don't all these range types have a common interface? I'd have to overload every single function for each of these range types and it would perform the exact same operations every time.

Are there any best practices yet for using ranges in Swift 3?

Answer Source

It's actually pretty simple:

A Closed...Range is produced by using three dots: 0...10. This includes lower bound and upper bound. The opposite is a non-closed range, produced by 0..<10 which doesn't include the upper bound.

A Countable...Range is a range of a type you can stride through with a signed integer, it is produced by either 0...10 or 0..<10. These types conform to the Sequence protocol.

A few examples:

0..<10 // CountableRange
0...Int.max // CountableClosedRange (this was not possible before Swift 3)

"A"..<"A" // Range, empty
"A"..."Z" // ClosedRange, because cannot stride through, only check if a character is in the bounds

You should probably make your methods accept a generic Collection/Sequence depending on what you need:

func test<C: Collection where C.Iterator.Element == Int>(s: C) {

Maybe you can show one of your uses for Range<Int>