Usando le affermazioni contro le eccezioni?


38

Spesso quando scrivo una funzione voglio assicurarmi che gli input siano validi al fine di rilevare tali errori il più presto possibile (credo che questi siano chiamati precondizioni). Quando una condizione preliminare fallisce, ho sempre lanciato un'eccezione. Ma sto iniziando a dubitare che questa sia la migliore pratica e, in caso contrario, affermazioni sarebbero più appropriate.

Quindi quando dovrei fare quale: quando è appropriato usare un'asserzione e quando è appropriato lanciare un'eccezione?


3
Penso che questa domanda dovrebbe essere posta su StackOverflow, anche se probabilmente è stata posta una dozzina di volte lì, quindi potresti già trovare molte risposte lì.
user281377,

Risposte:


50

Le asserzioni dovrebbero essere utilizzate solo per verificare condizioni che dovrebbero essere logicamente impossibili da falsificare (leggi: controlli di integrità). Queste condizioni dovrebbero basarsi solo su input generati dal proprio codice. Qualsiasi controllo basato su input esterni dovrebbe usare eccezioni.

Una semplice regola che tendo a seguire è la verifica degli argomenti delle funzioni private con asserzioni e l'utilizzo delle eccezioni per gli argomenti delle funzioni pubbliche / protette.


Un buon punto sull'uso delle eccezioni per input esterni. Aggiungerei anche output a questo - problemi quando
provo

13
E inevitabilmente troverai quelle asserzioni innescate nella produzione. +1 per la verifica di contenuti privati con assert! Forse potresti dire "usa assert quando hai il pieno controllo degli input"?
Frank Shearar,

1
Almeno in Java devi abilitare il controllo di asserzione con il parametro della riga di comando -ea. Ciò significa che le asserzioni sono effettivamente vietate, a meno che non le si attivi esplicitamente.
Bill Michell,

29

Le asserzioni vengono utilizzate per trovare errori di programmazione. I programmi devono funzionare altrettanto bene quando vengono rimosse tutte le asserzioni.

Le eccezioni, d'altra parte, sono per situazioni che possono accadere anche quando il programma è perfetto; sono causati da influenze esterne, come hardware, rete, utenti ecc.


Questo è un ottimo modo per dirlo. Se l'utente inserisce qualcosa di errato, genera un'eccezione. Se l'input è corretto ma qualcosa è ancora sbagliato, lancia un'asserzione.
Mateen Ulhaq,

3

La pratica di programmazione tipica è quella di compilare affermazioni da build di produzione / rilascio. Le asserzioni aiuteranno solo durante i test interni a rilevare il fallimento delle assunzioni. Non si deve assumere il comportamento di agenzie esterne, quindi non si deve far valere eventi dalla rete o dall'utente. Inoltre è buona norma scrivere codice di gestione per build di produzione nel caso in cui un'asserzione fallisca.

Ad esempio in C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Le eccezioni sono pensate per essere integrate nelle build di produzione. L'alternativa all'eccezione è la restituzione dell'errore e non delle asserzioni.


2
Non penso sia una buona idea mettere un comportamento aggraziato dietro un'affermazione per le stesse condizioni. Inevitabilmente, poiché il comportamento aggraziato esiste solo nella versione di produzione, il codice che avrebbe dovuto affrontare il comportamento aggraziato verrà scarsamente testato e si arresterà in modo anomalo quanto, se non peggio, il codice sarebbe se non fosse protetto.
Sebastian Redl,

0

Un problema con le asserzioni per me è che sono disabilitate di default in Java.

Usiamo una strategia fall-first in cui il programma - che potrebbe essere stato eseguito incustodito per anni - deve arrestarsi il più presto possibile per evitare la corruzione dei dati in caso di dati errati (su un modulo imprevisto). Questo è ciò per cui utilizziamo il controllo e, usando gli assert, sostanzialmente rischiamo che non siano attivi.

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.