2015-02-16 3 views
1

Привет, ребята, я здесь новый, и сейчас я изучаю Swift, кодируя некоторые причудливые алгоритмы, которые приходят мне на ум, читая книгу «Яблоки Свифт».Ошибка Swift range с сообщением switch

Я пытался сжать (автоматически понизить) любое значение IntegerType. Вот небольшой отрывок из моего кода, который почти отлично работает за исключением одного случая:

switch signedValue 
{ 
case Int64(Int8.min)...Int64(Int8.max):   compressedValue = Int8(signedValue) 
case (Int64(Int8.max) + 1)...Int64(UInt8.max): compressedValue = UInt8(signedValue) 
case Int64(Int16.min)...Int64(Int16.max):  compressedValue = Int16(signedValue) 
case (Int64(Int16.max) + 1)...Int64(UInt16.max): compressedValue = UInt16(signedValue) 
case Int64(Int32.min)...Int64(Int32.max):  compressedValue = Int32(signedValue) 
case (Int64(Int32.max) + 1)...Int64(UInt32.max): compressedValue = UInt32(signedValue) 
case Int64(Int.min)...Int64(Int.max):   compressedValue = Int(signedValue) // range bug #1 - workaround '..<' 
default:           compressedValue = signedValue 
} 

Пусть signedValue имеет тип Int64 и входное значение = 10_000_000_000. Это приведет к ошибке во время выполнения (в Playground):

Execution was interrupted, reason: EXC_BAD_INSTRUCTION ... 

Может кто-нибудь помочь мне понять, что именно здесь происходит. Обходной путь для этой проблемы. Вместо «...» я мог бы использовать «.. <», но это не так, как должен быть диапазон.

+0

Есть ли вероятность, что вы работаете на 32-битной платформе? –

+0

Нет, я работаю над MacBook Air 11 "(середина?) 2013 года, который должен быть 64 бит. Int.max имеет то же значение, что и Int64.max. – DevAndArtist

ответ

3

В отличие от интервалов (которые имеют два аромата, полуоткрытые или закрытые), Range только полуоткрыт. Поэтому, когда вы пишете 1...5, функция ... увеличивает правый аргумент, чтобы создать полуоткрытый диапазон 1..<6.

В результате этого вы не можете иметь диапазон, который охватывает всю длину целочисленного типа, так как 1...Int.max приведет к увеличению приращения Int.max и ошибке переполнения. Аналогичная ошибка с let s = "hello"; let r = s.startIndex...s.endIndex

Все не потеряно, однако, поскольку вы не должны использовать диапазоны в любом случае, это задание для ClosedInterval. Так как оператор ... используется для обоих, и по умолчанию диапазонов (для перегрузки причины старшинства), необходимо четко определить тип:

let i64interval: ClosedInterval = Int64(Int64.min)...Int64(Int64.max) 
switch signedValue { 
    // etc 
    case i64interval: compressedValue = Int(signedValue) 
    default:   compressedValue = signedValue 
} 
+0

Thx это помогло. Я не закончил читать книга и не знаю о «ClosedInterval» до сих пор. Кстати, также можно написать «case Int64 (Int64.min) ... Int64 (Int64.max) как ClosedInterval:« для решения моей проблемы. – DevAndArtist

3

Посмотрите на the documentation для Range типа. У этого есть следующий маленький самородок информации, который я никогда не замечал раньше:

Если T имеет максимальное значение, оно может служить в качестве endIndex, но никогда не может содержаться в диапазоне.

T, в этой цитате, является типом значения в Range. Поэтому, если у вас есть Range из Int s, максимальное значение Int не может содержаться в Range.

Именно поэтому он работает, если вы положили ..<, а не ....

Хороший вопрос, кстати ...

+0

Great , Я буду помнить об этом. Вероятно, я должен проверить документы перед тем, как спросить, но я не понимаю каждую ошибку Xcode, поэтому я мог бы найти проблему самостоятельно. – DevAndArtist

+0

Я нахожу, что сайт действительно полезен, потому что его так легко найти по типу, протоколу и т. д.Кроме того, если вы еще не обнаружили его, если вы наберете «import Swift» на игровой площадке, а затем нажмите «Swift», вы в основном получите основную часть общедоступной документации Apple Swift. –

+0

Нужно ли нам «импортировать Swift» для чего-нибудь? Щелчок команды на Int или любой другой тип Swift приведет к тому же. Для части документации я использую бесплатную версию «Dash». Хорошо, пусть это будет как есть, thx. Я не знаю, могут ли комментарии здесь быть немного не по теме. – DevAndArtist