So i have a problem using the Switch statement, when i used it with a range i get this "Fatal error: Range end index has no valid successor" in the console.
var ArrayBytes : [UInt8] = [48 ,48 ,48]
var SuperArrayMensaje : Array = [[UInt8]]()
var num7BM : Array = [UInt8]()
for var Cont27 = 0; Cont27 < 800; Cont27++ {
ArrayBytesReservaSrt = String(Mensaje7BM[Cont27])
switch Mensaje7BM[Cont27] {
case 0...9 :
num7BM = Array(ArrayBytesReservaSrt.utf8)
ArrayBytes.insert(num7BM[0], atIndex: 2)
case 10...99 :
num7BM = Array(ArrayBytesReservaSrt.utf8)
ArrayBytes.insert(num7BM[0], atIndex: 1)
ArrayBytes.insert(num7BM[1], atIndex: 2)
case 100...255 : // --> THE problem is here "EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"
num7BM = Array(ArrayBytesReservaSrt.utf8)
ArrayBytes.insert(num7BM[0], atIndex: 0)
ArrayBytes.insert(num7BM[1], atIndex: 1)
ArrayBytes.insert(num7BM[2], atIndex: 2)
default : break
}
SuperArrayMensaje.insert(ArrayBytes, atIndex: Cont27)
ArrayBytes = [48 ,48 ,48]
}
The problem can be reproduced with this MCVE:
let u = 255 as UInt8
switch u {
case 0...9: print("one")
case 10...99: print("two")
case 100...255: print("three")
}
And to a degree, we see the problem if we simply try to create a range variable that would cover this range:
let r = Range<UInt8>(start: 100, end: 256)
This doesn't compile. First, we must note that the end
argument for the Range
constructor is not included in the range.
The range 100...255
is equivalent to 100..<256
. If we try to construct that range, we get the compile error:
Integer literal '256' overflows when stored into 'UInt8'
We can't create a range which includes the max value for that integer type. Problematically, there's no UInt8
value larger than 255
. That's needed because for something to be contained within a range, it must be smaller than the end
value of the range. That is, it must return true when compared with the <
operator. And there's no UInt8
value that can make this statement: 255 < n
return true. Therefore, 255
can never be in a range of type UInt8
.
So, we have to find a different approach.
As the programmer, we can know that the range we're trying to create representing all the three digit decimal numbers that fit in UInt8
, we could just use the default
case here:
let u = 255 as UInt8
switch u {
case 0...9: print("one")
case 10...99: print("two")
default: print("three")
}
This seems the simplest solution. I like this option best because we don't end up with a default
case that we know will never execute.
If we really explicitly want a case that captures all of the values from 100
to UInt8
max, we can also do this:
switch u {
case 0...9: print("one")
case 10...99: print("two")
case 100..<255, 255: print("three")
default: print("how did we end up here?")
}
Or like this:
switch u {
case 0...9: print("one")
case 10...99: print("two")
case 100...255 as ClosedInterval: print("three")
default: print("default")
}
For more reading on the ClosedInterval
, see the Apple documentation or Swift doc.