Differenza tra "precondizione" e "asserzione" in swift?


105

Qual è la differenza tra precondition(condition: Bool, message: String)e assert(condition: Bool, message: String)in Swift?

Entrambi mi sembrano uguali. In quale contesto dovremmo usarne uno sull'altro?

Risposte:


125

assertserve per i controlli di integrità durante i test, mentre preconditionè per proteggersi da cose che, se accadessero, significherebbero che il tuo programma non potrebbe ragionevolmente procedere.

Quindi, ad esempio, potresti inserire un assertcalcolo con risultati ragionevoli (entro alcuni limiti, diciamo), per trovare rapidamente se hai un bug. Ma non vorresti spedirlo con quello, dal momento che il risultato fuori limite potrebbe essere valido e non critico, quindi non dovresti bloccare la tua app (supponiamo che tu lo stia usando solo per visualizzare i progressi in una barra di avanzamento).

D'altra parte, controllare che un pedice su un array sia valido quando si scarica un elemento è un file precondition. Non vi è alcuna azione successiva ragionevole da intraprendere per l'oggetto array quando viene richiesto un indice non valido, poiché deve restituire un valore non facoltativo.

Testo completo dai documenti (prova a fare clic sull'opzione asserte preconditionin Xcode):

Presupposto

Verificare una condizione necessaria per fare progressi.

Utilizzare questa funzione per rilevare le condizioni che devono impedire al programma di procedere anche nel codice di spedizione.

  • In playground e build -Onone (l'impostazione predefinita per la configurazione di debug di Xcode): se conditionrestituisce false, interrompe l'esecuzione del programma in uno stato debuggabile dopo la stampa message.

  • In -O build (l'impostazione predefinita per la configurazione di rilascio di Xcode): se conditionrestituisce false, interrompe l'esecuzione del programma.

  • In -Ounchecked costruisce, conditionnon viene analizzato, ma l'ottimizzatore può supporre che sarebbe valutata come true. L'incapacità di soddisfare tale presupposto nelle build -Ounchecked è un grave errore di programmazione.

Asserire

Affermazione in stile C tradizionale con un messaggio opzionale.

Utilizzare questa funzione per i controlli di integrità interna che sono attivi durante i test ma non influiscono sulle prestazioni del codice di spedizione. Per verificare l'utilizzo non valido nelle build di rilascio; vedere precondition.

  • In playground e build -Onone (l'impostazione predefinita per la configurazione di debug di Xcode): se conditionrestituisce false, interrompe l'esecuzione del programma in uno stato debuggabile dopo la stampa message.

  • In -O build (l'impostazione predefinita per la configurazione di rilascio di Xcode), conditionnon viene valutato e non ci sono effetti.

  • In -Ounchecked costruisce, conditionnon viene analizzato, ma l'ottimizzatore può supporre che sarebbe valutata come true. L'incapacità di soddisfare tale presupposto nelle build -Ounchecked è un grave errore di programmazione.


2
"Ma non vorresti spedire con quello, dal momento che il risultato fuori limite potrebbe essere valido e non critico, quindi non dovresti mandare in crash la tua app" è molto vago per me. Puoi gentilmente includere un esempio esatto? Forse un codice.
Miele

2
Rispondendo alla tua domanda, utilizzo personalmente le affermazioni per catturare cose che non dovrebbero accadere nella mia build mentre la scrivo e la collaudo. Immagina una dichiarazione di guardia che legge JSON dove data["name"]non esiste, ma dovrebbe. Avere un'asserzione all'interno della guardia..else {} mi aiuterebbe a rilevare il mio errore bloccandomi e portandomi al problema. Allo stesso modo, se questo codice fosse in produzione, l'assert non manderebbe in crash il programma e qualunque codice di backup che ho usato ( return nil) prenderebbe il sopravvento.
Alec O,

1
Non dovresti controllare l'indice e non fare nulla invece di mandare in crash l'intera app?
Iulian Onofrei

Sì, dovresti controllare l'indice, ma a volte tutti sbagliano e l'uso di asserzioni ti aiuta a capire che avresti dovuto controllare l'indice quando ti sei dimenticato.
Victor Engel

"Ma non vorresti spedire con quello, dal momento che il risultato fuori limite potrebbe essere valido e non critico, quindi non dovresti mandare in crash la tua app". Puoi spedire la tua app con tutte le affermazioni che desideri. Swift semplicemente non valuterà le tue condizioni all'interno del blocco di asserzioni nell'app di rilascio
Akshansh Thakur il

90

Ho scoperto che Swift afferma: il manuale mancante è utile

                        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

E da discussioni interessanti su Swift Evolution

- asserire: controllare il proprio codice per errori interni

- presupposto: per verificare che i tuoi clienti ti abbiano fornito argomenti validi.

Inoltre, devi stare attento a cosa usare, vedi assertionFailure e Livello di ottimizzazione


Puoi approfondire la differenza del codice e del client? Per quanto riguarda client intendi come inserire numeri dove è prevista una stringa? Non dovrebbe essere trattato con una semplice gestione degli errori?
Miele

@ Tesoro, penso che intenda parlare degli argomenti / risultati della chiamata API di rete o dei plug-in del cliente.
Chen Li Yong

Il cliente potrebbe essere qualcuno che usa il tuo codice, supponiamo che tu stia scrivendo una libreria e un programmatore trasmette dati non validi. Non vorrai continuare con grazia poiché potrebbe essere considerato un grave errore di programmazione. Probabilmente non dovresti mai andare in crash su dati API di rete non validi poiché ciò è molto inutile per l'utente.
bompf

@ onmyway133: da Xcode QuickHelp, penso precondition()e preconditionFailure()stanno avendo gli stessi comportamenti . La differenza tra queste funzioni è: preconditionserve una condizione interna, mentre preconditionFailurebutta fuori.
nahung89

12

Il preconditionè attivo in modalità di rilascio in modo da quando spedite la vostra applicazione e il presupposto fallito l'applicazione terminerà. Assertfunziona solo in modalità debug come impostazione predefinita.

Ho trovato questa ottima spiegazione quando usarlo su NSHipster:

Le asserzioni sono un concetto preso in prestito dalla logica classica. In logica, le asserzioni sono dichiarazioni su proposizioni all'interno di una dimostrazione. Nella programmazione, le asserzioni denotano le ipotesi che il programmatore ha fatto sull'applicazione nel luogo in cui sono dichiarate.

Quando vengono utilizzate nella capacità di precondizioni e postcondizioni, che descrivono le aspettative sullo stato del codice all'inizio e alla fine dell'esecuzione di un metodo o di una funzione, le asserzioni formano un contratto. Le asserzioni possono essere utilizzate anche per applicare condizioni in fase di esecuzione, al fine di impedire l'esecuzione quando determinate condizioni preliminari falliscono.


Le asserzioni possono essere abilitate e disabilitate utilizzando un flag del compilatore; possono essere attivi nel codice spedito.
Pétur Ingi Egilsson

6

presupposto

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

Verificare una condizione necessaria per fare progressi.

  1. Utilizzare questa funzione per rilevare le condizioni che devono impedire al programma di procedere anche nel codice di spedizione.
  2. In playground e build -Onone (il valore predefinito per la configurazione di debug di Xcode): se la condizione restituisce false, interrompi l'esecuzione del programma in uno stato debuggabile dopo la stampa del messaggio.
  3. In -O build (l'impostazione predefinita per la configurazione di rilascio di Xcode): se la condizione restituisce false, interrompe l'esecuzione del programma.
  4. Nelle build -Ounchecked, la condizione non viene valutata, ma l'ottimizzatore può presumere che restituirebbe true. L'incapacità di soddisfare tale presupposto nelle build -Ounchecked è un grave errore di programmazione.

asserire

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

Affermazione in stile C tradizionale con un messaggio opzionale.

  1. Utilizzare questa funzione per i controlli di integrità interna che sono attivi durante i test ma non influiscono sulle prestazioni del codice di spedizione. Per verificare l'utilizzo non valido nelle build di rilascio; vedi precondizione.

  2. In playground e build -Onone (il valore predefinito per la configurazione di debug di Xcode): se la condizione restituisce false, interrompi l'esecuzione del programma in uno stato debuggabile dopo la stampa del messaggio.

  3. Nelle build -O (l'impostazione predefinita per la configurazione di rilascio di Xcode), la condizione non viene valutata e non ci sono effetti
  4. Nelle build -Ounchecked, la condizione non viene valutata, ma l'ottimizzatore può presumere che restituirebbe true. La mancata soddisfazione di tale presupposto nelle build -Ounchecked è un grave errore di programmazione

0

Volevo solo aggiungere i miei 2 centesimi. Puoi aggiungere tutte le asserzioni nel codice che desideri. Puoi spedire il tuo codice con queste affermazioni. Swift NON valuta questi blocchi di codice per le app di produzione. Questi vengono valutati solo in caso di modalità di debug.

Aggiunta di collegamento alla documentazione

Allegando anche un'immagine da swift.org

inserisci qui la descrizione dell'immagine

Si noti inoltre che questo non è il caso delle precondizioni. Il codice fornito con le precondizioni andrà in crash e l'app verrà chiusa se le precondizioni non vengono valutate come vere.

Quindi, in breve, le asserzioni sono per il debug, ma possono essere spedite senza influire sulla produzione. Le asserzioni verranno valutate in modalità debug ma non in produzione.

E

Le condizioni preliminari sono per assicurarsi che cose impreviste non accadano nell'ambiente di produzione. Tali condizioni vengono valutate e interromperanno l'app nel caso in cui vengano valutate come false

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.