2015-09-18 2 views
1

Это не работает (конечно) ничего не печатает и Xcode выплевывает предупреждение о ролях всегда неисправные:Swift преобразование BOOL в NSRange

let bool = true 
if let range = bool as? NSRange { 
    print(range) 
} 

Почему это работает? Я думаю, что это не должно:

let bool: AnyObject = true  
if let range = bool as? NSRange { 
    print(range) 
} 

Это на самом деле распечатать (0,0) ... что может отчасти иметь смысл, если бы это было false, но это true так, да ... не имеет смысла для меня ,

Такое же поведение в Swift 1.2 или 2.0. Но это немного заставляет меня сомневаться в системе типа Свифта.

ответ

1

Это не столько проблема системы типа Swift, сколько побочного эффекта взаимодействия Objective-C.

let bool: AnyObject = true фактически let bool = NSNumber(bool: true). Это уже не Swift Bool, но это объект NSNumber Obj-C (Foundation).

Затем let range = bool as? NSRange пытается преобразовать ваше значение в NSRange. NSNumber является подклассом NSValue, поэтому это похоже на

let range = NSNumber(bool: true).rangeValue 

, который возвращает {0,0}. Вот как работает NSValue. Вот некоторые разборки с Хоппера:

disassembly

Это может быть поправимо с точки зрения Свифта команды, если они более осторожны проверками типа перед выполнением преобразования. Вы должны рассмотреть filing a bug.

+0

Это имеет смысл, хотя оно также нарушает предположение о том, что я имел дело с оператором 'as? ', А именно, что он проверяет только определенные типы и ничего больше. Я не понимал, что это также будет стимулировать ценности. Насколько я могу судить, это происходит только с «AnyObject» ... Я не уверен, что я должен указать на ошибку. Похоже, это намеченное поведение. –

+0

Есть ли способ определить исходный тип значения? Похоже, что информация о типе теряется, когда она преобразуется в 'NSNumber'. Может потребоваться опубликовать еще один вопрос о том, что ... –

+0

Вы можете использовать 'objCType', чтобы получить представление, но он не будет идеальным (NSNumber не всегда сохраняет точный тип). Вы могли бы также рассмотреть «как? NSNumber' выполнить проверку класса без принуждения. Но я бы рекомендовал просто избегать смешивания NSRange с NSNumbers. Вам действительно нужно использовать AnyObject здесь? – jtbandes

Смежные вопросы