Неустранимая ошибка: индекс конца диапазона не имеет действительного преемника

Так что у меня есть проблема с использованием оператора Switch, когда я использовал его с диапазоном, я получаю в консоли "Неустранимая ошибка: у индекса конца диапазона нет действительного преемника".

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]
    }

1 ответ

Решение

Проблема может быть воспроизведена с этим MCVE:

let u = 255 as UInt8

switch u {
case 0...9: print("one")
case 10...99: print("two")
case 100...255: print("three")
}

И в некоторой степени мы видим проблему, если просто пытаемся создать переменную диапазона, которая бы охватывала этот диапазон:

let r = Range<UInt8>(start: 100, end: 256)

Это не компилируется. Во-первых, мы должны отметить, что end аргумент в пользу Range Конструктор не входит в ассортимент.

Диапазон 100...255 эквивалентно 100..<256, Если мы попытаемся построить этот диапазон, мы получим ошибку компиляции:

Целочисленный литерал "256" переполняется при сохранении в "UInt8"

Мы не можем создать диапазон, который включает максимальное значение для этого целочисленного типа. Проблемно нет UInt8 значение больше чем 255, Это необходимо, потому что для того, чтобы что-то содержалось в пределах диапазона, оно должно быть меньше, чем end значение диапазона. То есть он должен возвращать true при сравнении с < оператор. И нет UInt8 Значение, которое может сделать это утверждение: 255 < n верните истину. Следовательно, 255 никогда не может быть в диапазоне типа UInt8,

Итак, мы должны найти другой подход.

Как программист, мы можем знать, что диапазон, который мы пытаемся создать, представляет все трехзначные десятичные числа, которые соответствуют UInt8 мы могли бы просто использовать default случай здесь:

let u = 255 as UInt8

switch u {
case 0...9: print("one")
case 10...99: print("two")
default: print("three")
}

Это кажется самым простым решением. Мне больше нравится этот вариант, потому что мы не получаем default Случай, который мы знаем, никогда не будет выполнен.

Если мы действительно явно хотим случай, который захватывает все значения из 100 в UInt8 Макс, мы также можем сделать это:

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?")
}

Или вот так:

switch u {
case 0...9: print("one")
case 10...99: print("two")
case 100...255 as ClosedInterval: print("three")
default: print("default")
}

Для получения дополнительной информации о ClosedInterval см. документацию Apple или документацию Swift.

Другие вопросы по тегам