Быстрая хорошая практика кодирования: если инструкция с дополнительным типом Bool
Итак, я разрабатывал приложение в Swift, и сегодня я потратил почти час на отладку проблемы, которая оказалась совершенно неожиданной. Все это было результатом кода ниже.
if (hero.isAI) { //isAI is a Bool
}
Проблема заключалась в том, что этот оператор if ALWAYS возвратил true. Поэтому я подумал, что, возможно, я устанавливал isAI в true, но в конце я понял, что объявил isAI как необязательный тип, как показано ниже.
var isAI: Bool!
когда это должно было быть
var isAI: Bool
Это привело к тому, что if-statement не проверял, является ли isAI истинным, но вместо этого проверяет, содержит ли оно значение.
Итак, чтобы быть в безопасности, я обязательно буду писать мои if-statments, подобные этому
if (hero.isAI == true) { //isAI is a Bool
}
Итак, мой вопрос: , каковы мои варианты, чтобы избежать этой проблемы в будущем? (эта проблема кажется чрезвычайно опасной, особенно при работе над командой над крупным проектом).
Должен ли я всегда писать свой if-statment явно, должен ли я просто избегать необязательного типа для Bools?
Обратите внимание, что у меня не было этой проблемы в Xcode Beta 2. Эта проблема возникла, когда я обновился до Xcode beta 3. Я думаю, потому что в Beta 2 Apple обрабатывает неявно развернутый Bool в if-statement, проверяя его значение, а не проверяя, содержит ли оно значение.
Наконец, ниже приведен пример того, какие if-statements запускаются с учетом необязательного Bool, чтобы лучше помочь людям понять проблему.
let myBool: Bool! = false
if (myBool) {
//Runs
}
if (myBool!) {
//Won't Run
}
if (!myBool) {
//Runs
}
if (myBool == true) {
//Won't Run
}
Ответы
Ответ 1
Это известная проблема, которая отслеживается в репозитории SwiftInFlux, который включает эту цитату из Криса Латтнера на форумах разработчиков Apple.
Эта проблема существует с любым необязательным чем-то, что соответствует протокол LogicValue (например, вложенные опции, необязательные для bool, и т.д). Мы считаем это серьезной проблемой, которую нужно исправить на 1.0 и есть некоторые идеи, но еще не определились с решением.
Таким образом, эта проблема влияет не только на необязательные Bools, но и на любой необязательный тип, который соответствует протоколу LogicValue (определен как).
protocol LogicValue {
func getLogicValue() -> Bool
}
В любом случае, что касается рекомендаций, как обойти это, трудно рекомендовать какое-либо одно конкретное решение, учитывая, что Apple не дала указание о том, как они намерены решить эту проблему в будущем, но я полагаю, что продолжать явно проверять значение Bool было бы хорошим способом.
if (hero.isAI == true) {
// stuff
}
Фактически, после некоторого дальнейшего прочтения цитата, приведенная выше, продолжает звучать так:
Для этого распространенного случая самый простой ответ - получить предупреждение за "если х" и требует, чтобы кто-то явно написал "если х! = ноль "или" если x == true ", чтобы сделать это явно, что они хотят.
Ответ 2
Мой совет - использовать этот хороший коалесцирующий ??
if textfieldDate.text?.isEmpty ?? true {
// the text is either nil or empty but its all we want to know
}
Ответ 3
Если bool является частью Core Data (aka NSNumber), вы должны сделать это следующим образом.
if (isHero.isAI?.boolValue != nil)
Привет