Update: Easy fix from Joachim and Jacob, proving that my brain is fried. Joachim notes: ” Range and Interval have been separated into separate classes during the beta. … Creates either depending on context.”
I’ve been playing recently with custom operators. The operator grammar in the Swift Programming Language is a bit obtuse as it lists ranges of unicode characters instead of just showing you a table of what the legal ones are. (There are a lot.) So I hopped into a playground hoping to iterate through them to see if any nice/intriguing/helpful characters popped up. What followed was an interesting exploration of arrays of ranges.
I started by creating a basic list of items I wanted to look at, using the list of “operator-head”-compatible hex values.
var ranges : [Range<Int>] = [ 0xA1...0xA7, 0xA9...0xA9, 0xAB...0xAB, 0xAC...0xAC, 0xB0...0xB1, 0xB6...0xB6, 0xBB...0xBB, 0xBF...0xBF, 0xD7...0xD7, 0xF7...0xF7, 0x2016...0x2017, 0x2020...0x2027, 0x2030...0x203E, 0x2041...0x2053, 0x2055...0x205E, 0x2190...0x23FF, 0x2500...0x2775, 0x2794...0x2BFF, 0x2E00...0x2E7F, 0x3001...0x3003, 0x3008...0x3030, ]
But when I attempted to iterate, I ran into errors that ClosedInterval<Int> items do not conform to SequenceType protocols:
for range in ranges { for item in range { var unicode = String(UnicodeScalar(item)) println(String(format:"0x%X: \(unicode)", item)) } }
Instead, I had to create a new range out of the interval as follows:
for range: ClosedInterval<Int>in ranges {
for item inrange.start...range.endrange { var unicode = String(UnicodeScalar(item)) println(String(format:"0x%X: \(unicode)", item)) } } Thanks Joachim and Jacob for fixes.
I think my brain is too dead this morning to really think about this in depth but it seems to me a bit odd that I had to work around this in this way, since a closed interval is intrinsically range-y. (Update: Fixed.)
Most of the operator-ready characters by the way are pretty meh but that’s an entirely different post.
One Comment
I think Swift’s type inference is falling down here and giving you problems. `…` can return either a Range or a ClosedInterval, and it’s up to the compiler to choose which unless you specify. (Airspeed Velocity has a great series on that topic.)
Assigning a single value gives you a
Range<Int>
:let range = 0x3008...0x3030
But in an array literal, the compiler reads it as
[ClosedInterval<Int>]
:let ranges = [ 0x3008...0x3030, ... ]
As a solution, you can give your
ranges
array an explicit type:let ranges: [Range<Int>] = [ 0x3008...0x3030, ... ]