Немного общей картины, чтобы добавить к другим полезным, но более детальным ответам:
В Swift восклицательный знак появляется в нескольких контекстах:
- Принудительное разворачивание:
let name = nameLabel!.text
- Неявно развернутые опции:
var logo: UIImageView!
- Принудительный кастинг:
logo.image = thing as! UIImage
- Необработанные исключения:
try! NSJSONSerialization.JSONObjectWithData(data, [])
Каждый из них представляет собой разную языковую конструкцию с разным значением, но все они имеют три общие общие черты:
1. Восклицательные знаки обходят проверки безопасности Swift во время компиляции.
Когда вы используете !
в Swift, вы, по сути, говорите: «Эй, компилятор, я знаю, что вы думаете, что здесь может произойти ошибка, но я знаю с полной уверенностью, что это никогда не произойдет. буду."
Не весь допустимый код вписывается в рамки системы типов времени компиляции Swift - или проверки статических типов любого языка, если на то пошло. Бывают ситуации, когда вы можете логически доказать, что ошибки никогда не произойдет, но не можете доказать это компилятору. Именно поэтому дизайнеры Swift в первую очередь добавили эти функции.
Однако всякий раз, когда вы используете !
, вы исключаете возможность восстановления после ошибки, что означает, что ...
2. Восклицательные знаки - потенциальные аварии.
Восклицательный знак также говорит: «Привет, Свифт, я настолько уверен, что эта ошибка никогда не может произойти, поэтому лучше для вас вывести из строя все мое приложение, чем мне запрограммируйте для него путь восстановления ".
Это опасное утверждение. Он может быть правильным: в критически важном коде, когда вы хорошо обдумываете инварианты своего кода, может оказаться, что фиктивный вывод хуже, чем сбой.
Однако, когда я вижу !
в дикой природе, он редко используется так осознанно. Вместо этого это слишком часто означает: «это значение было необязательным, и я особо не задумывался о том, почему он может быть равен нулю или как правильно справиться с этой ситуацией, но добавление !
заставило его скомпилировать ... так что мой код правильный, верно? "
Остерегайтесь высокомерия восклицательного знака. Вместо…
3. Восклицательные знаки лучше всего использовать экономно.
У каждой из этих !
конструкций есть ?
аналог, который заставляет вас иметь дело с случаем error / nil:
- Условная распаковка:
if let name = nameLabel?.text { ... }
- Варианты:
var logo: UIImageView?
- Условное приведение:
logo.image = thing as? UIImage
- Нулевые исключения при сбое:
try? NSJSONSerialization.JSONObjectWithData(data, [])
Если вы испытываете искушение использовать !
, всегда хорошо подумать, почему вы не используете вместо этого ?
. Действительно ли сбой вашей программы - лучший вариант, если операция !
завершится неудачно? Почему это значение необязательное / недопустимое?
Есть ли разумный путь восстановления, который ваш код мог бы использовать в случае нулевого значения / ошибки? Если да, закодируйте это.
Если он не может быть равен нулю, если ошибка никогда не может произойти, то есть ли разумный способ переделать вашу логику, чтобы компилятор знал об этом? Если так, сделайте это; ваш код будет менее подвержен ошибкам.
Бывают случаи, когда нет разумного способа обработать ошибку, и простое игнорирование ошибки - и, следовательно, обработка неверных данных - было бы хуже, чем сбой. - самое время применить принудительное разворачивание.
Я периодически ищу !
во всей кодовой базе и проверяю каждое его использование. Очень немногие обычаи выдерживают проверку. (На момент написания этой статьи во всей структуре Siesta было ровно два экземпляры.)
Это не значит, что вы не должны никогда использовать !
в своем коде - просто вы должны использовать его осознанно и никогда не использовать его по умолчанию.
person
Paul Cantrell
schedule
28.10.2015