Різниця між "передумовою" та "стверджувати" у швидкому?


105

Яка різниця між precondition(condition: Bool, message: String)та assert(condition: Bool, message: String)у Свіфті?

Вони обидва на мене виглядають однаково. У якому контексті ми повинні використовувати одне над іншим?

Відповіді:


125

assertпризначений для перевірки стану здоров'я під час тестування, тоді preconditionяк для захисту від речей, які, якщо вони відбудуться, означали б, що ваша програма просто не може розумно продовжувати роботу.

Так, наприклад, ви можете покласти assertна якийсь розрахунок, який має розумні результати (скажімо, в деяких межах), щоб швидко виявити, чи є у вас помилка. Але ви не хочете поставлятися з цим, оскільки результат, який знаходиться поза межами, може бути дійсним і не критичним, тому не повинен збивати додаток (припустимо, ви просто використовували його для відображення прогресу на панелі прогресу).

З іншого боку, перевірка на те, що підпис на масиві є дійсним під час отримання елемента, є a precondition. Немає жодної розумної наступної дії для об’єкта масиву, який слід здійснити, коли його запитують про недійсний індекс, оскільки він повинен повертати необов'язкове значення.

Повний текст із документів (спробуйте клацнути параметр assertта preconditionв Xcode):

Передумова

Перевірте необхідну умову для досягнення прогресу вперед.

Використовуйте цю функцію для виявлення умов, які повинні перешкоджати роботі програми навіть у коді доставки.

  • На ігрових майданчиках та -Onone збирає (за замовчуванням для конфігурації налагодження Xcode): якщо conditionоцінюється як false, зупиніть виконання програми у стані налагодження після друку message.

  • Вбудовує -O (за замовчуванням для конфігурації випуску Xcode): якщо conditionоцінюється як false, зупиніть виконання програми.

  • У -Ounchecked будує, conditionне оцінює, але оптимізатор може припустити , що вона буде обчислюватися true. Невиконання цього припущення в -провірених побудовах є серйозною помилкою програмування.

Затвердити

Традиційне твердження у стилі С із додатковим повідомленням.

Використовуйте цю функцію для внутрішніх перевірок санітарності, які активні під час тестування, але не впливають на продуктивність коду доставки. Щоб перевірити недійсне використання у версії версій; див precondition.

  • На ігрових майданчиках та -Onone збирає (за замовчуванням для конфігурації налагодження Xcode): якщо conditionоцінюється як false, зупиніть виконання програми у стані налагодження після друку message.

  • In -O збірки (за замовчуванням для конфігурації випуску Xcode), conditionне оцінюються, і ефектів немає.

  • У -Ounchecked будує, conditionне оцінює, але оптимізатор може припустити , що вона буде обчислюватися true. Невиконання цього припущення в -провірених побудовах є серйозною помилкою програмування.


2
"Але ви не хотіли б із цим поставлятись, оскільки позамежений результат може бути дійсним, а не критичним, тому не повинен виходити з ладу ваш додаток", що для мене дуже розпливчасте. Будь ласка, ви можете включити точний приклад? Можливо, якийсь код.
Мед

2
Відповідаючи на ваше запитання, я особисто використовую твердження, щоб спіймати речі, які просто не повинні відбуватися в моєму складі, поки я пишу і тестую його. Уявіть заяву охоронця, що читає JSON там, де data["name"]його немає, але воно повинно. Стверджуючи, що знаходиться всередині охоронця. Інакше {} допоможе мені зрозуміти мою помилку, врізавшись і привівши мене до проблеми. Аналогічно, якби цей код був у виробництві, асдрад не зірвав би програму, і будь-який резервний код, який я використовував ( return nil), взяв би на себе.
Alec O

1
Чи не слід перевіряти індекс і не робити нічого замість того, щоб зламати весь додаток?
Юліан Онофрей

Так, ви повинні перевірити індекс, але кожен інколи прослизає, і за допомогою аскретів ви зможете зрозуміти, що ви повинні перевірити індекс, коли забули.
Віктор Енгель

"Але ви не хочете поставляти з цим, оскільки результат, пов'язаний із обмеженням, може бути дійсним, але не критичним, тому не повинен збій вашої програми". Ви можете відправити додаток з якоюсь кількістю тверджень, скільки вам потрібно. Свіфт просто не оцінить ваші умови всередині блоку тверджень у додатку до випуску
Акшанш Такур

90

Я знайшов твердження Свіфта - відсутній посібник буде корисним

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

І з цікавих дискусій про швидку еволюцію

- стверджувати: перевірка власного коду на наявність внутрішніх помилок

- передумова: перевірити, чи ваші клієнти дали вагомі аргументи.

Крім того, вам слід бути обережними щодо того, чим користуватися, див. ТвердженняFailure та Optimization Level


Чи можете ви детальніше розглянути різницю власного коду та клієнта? Що стосується клієнта, ти маєш на увазі, як вставляти номери, де очікується рядок? Чи не слід це ставитися до простого поводження з помилками?
Мед

@Honey Я думаю, що він має на увазі аргументи / результати від виклику мережевого API або власних плагінів клієнта.
Чень Лі Йонг

Клієнтом буде хтось, хто використовує ваш код, скажімо, ви пишете бібліотеку, а програміст передає недійсні дані. Ви не хочете витончено продовжувати, оскільки це може вважатися серйозною помилкою програмування. Напевно, ви ніколи не повинні збиватися з недійсних даних мережевих API, оскільки це дуже корисно для користувача.
bompf

@ Onmyway133: Від Xcode QuickHelp, я думаю , precondition()і preconditionFailure()які мають ті ж моделі поведінки . Різниця між цими функціями полягає в тому, що: preconditionпотрібна умова всередині, а preconditionFailureпросто викиньте.
nahung89

12

preconditionАктивно в режимі випуску , так що ви , коли ви відправляєте ваше додаток і попередня умова не вдалося додаток завершиться. Assertпрацює як раз у режимі налагодження за замовчуванням.

Я знайшов це чудове пояснення, коли його використовувати на NSHipster:

Твердження - це поняття, запозичене з класичної логіки. За логікою, твердження - це твердження про пропозиції в рамках доказу. У програмуванні твердження позначають припущення, які програміст зробив щодо програми в тому місці, де вони оголошені.

При використанні в якості передумов і постумов, які описують очікування щодо стану коду на початку та в кінці виконання способу чи функції, твердження формують договір. Твердження також можуть використовуватися для забезпечення виконання умов під час виконання, щоб запобігти виконанню, коли певні передумови виходять з ладу.


Твердження можна вмикати та вимикати, використовуючи прапор компілятора; вони можуть бути активними в відправленому коді.
Петур Інгі Егілссон

6

передумова

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

Перевірте необхідну умову для досягнення прогресу вперед.

  1. Використовуйте цю функцію для виявлення умов, які повинні перешкоджати роботі програми навіть у коді доставки.
  2. На ігрових майданчиках та -Onone збирає (за замовчуванням для конфігурації налагодження Xcode): якщо умова оцінюється як помилкове, зупиніть виконання програми у стані налагодження після друку повідомлення.
  3. Вбудовує -O (за замовчуванням для конфігурації випуску Xcode): якщо умова оцінюється на помилкове, зупиніть виконання програми.
  4. У -провірених побудовах стан не оцінюється, але оптимізатор може припустити, що він буде оцінювати як істинне. Невиконання цього припущення в -провірених побудовах - це серйозна помилка програмування.

стверджувати

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

Традиційне твердження у стилі С із додатковим повідомленням.

  1. Використовуйте цю функцію для внутрішніх перевірок санітарності, які активні під час тестування, але не впливають на продуктивність коду доставки. Щоб перевірити недійсне використання у версії версій; див. передумову.

  2. На ігрових майданчиках та -Onone збирає (за замовчуванням для конфігурації налагодження Xcode): якщо умова оцінюється як помилкове, зупиніть виконання програми у стані налагодження після друку повідомлення.

  3. У складі -O (за замовчуванням для конфігурації випуску Xcode), стан не оцінюється, і ефектів немає
  4. У -провірених побудовах стан не оцінюється, але оптимізатор може припустити, що він буде оцінювати як істинне. Невиконання цього припущення в -провірених побудовах є серйозною помилкою програмування

0

Просто хотів додати свої 2 копійки. Ви можете додати стільки тверджень у свій код, скільки хочете. Ви можете відправити код за допомогою цих тверджень. Swift НЕ оцінює ці кодові блоки для виробничих додатків. Вони оцінюються лише у випадку налагодження.

Додавання посилання на документацію

Також додається зображення з swift.org

введіть тут опис зображення

Також зауважте, що це не стосується передумов. Код, поставлений з передумовами, вийде з ладу, і додаток припиниться, якщо попередні умови не будуть оцінені як істинні.

Отже, коротше, твердження призначені для налагодження, але їх можна відправляти, не впливаючи на виробництво. Твердження будуть оцінені в режимі налагодження, але не у виробництві.

І

PreConditions - це переконання, що на виробничому середовищі не трапляються несподівані речі. Ці умови оцінюються, і додаток буде припинено, якщо він буде помилковим

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.