Bruke try..except å håndtere errors

Lær om unntak og hvordan å skrive bedre feilhåndtering kode. Lær hvordan Castalia kan hjelpe oss å skrive mer robust og feiltolerant kode.
(Opprinnelig publisert på delphi-expert.com 23. mars 2004)
Som lovet, er i dag en del to av vår diskusjon av Delphi prøve konstruksjoner. Forrige uke så vi på try..finally, lært hva den er ment for, når man skal bruke det, og hvordan Castalia kan hjelpe oss bruke det mer effektivt. Denne uken vil vi undersøke den andre halvdelen av forsøk familie, try..except og lære hvordan Castalia kan gjøre våre try..except bruk mer effektive. Vi vil også gjøre narr av java
Try..except er en konstruksjon for å håndtere ". Eksepsjonell " situasjoner i et program. Et program som har en typisk strømnings, som er et sett med instruksjoner som går videre i rekkefølge. Noen ganger denne ordren innebærer grener, men det er alltid en logisk flyt, og beslutninger til gren som strøm baseres på noen state of the program, som enten X er mindre enn 5.
noen ganger, men at staten kan bli gjengitt feil . La oss ta et eksempel som vi kan se i den virkelige verden:
AssignFile (F, 'SomeFile.Txt'); ResetFile (F); S: = ReadLn (F); CloseFile (F),
Denne enkle koden vil åpne en fil, lese en linje fra det, og lukker den igjen. Dette er den normale strømningen av programmet. Imidlertid er gjort en rekke forutsetninger om denne flyten. Først antar vi at filen finnes. Vi antar at vi kan åpne den for å lese. Vi antar at det er en linje for å bli lest. Osv ...
Hvis noen av disse forutsetningene viser seg å være falsk, så har vi en eksepsjonell situasjon! Flyten av programmet kommer til å bli rotet opp av det faktum at noen stat er ikke staten vi forventet.
Det er flere måter å håndtere disse unntakssituasjoner. Vi kunne ignorere dem, og om noen av dem oppstår, vil programmet krasje eller gjøre noe annet like uberegnelig. Vi kunne se etter disse unntakene, og legger til kode som dette:
om ikke FileExists ('SomeFile.txt') thenbegin WriteLn ('Filen eksisterer ikke'); Exit; end;
Dette er bedre. For det første har du faktisk fortalte brukeren hvorfor programmet ikke vil fungere. For enkle programmer, dette fungerer godt, men som programmet blir mer og mer komplekse, vil staten av programmet blir eksponentielt komplekse, og snart vil du være i stand til å sjekke alle forutsetninger. Kontrollere forutsetninger er en god ting om. Vi kommer tilbake til dette senere.
Vi kan også checkafter hver operasjon for å være sikker på at det vi forventet å skje. Dette er den tradisjonelle C tilnærming, og tilnærming av Windows API (og de fleste andre operativsystem APIer, med BeOS som ett unntak). I denne modellen, returnerer hver funksjon en feilkode. Det er ditt ansvar å kontrollere feilkoden og se om det er " OK " eller noe annet som FILE_NOT_FOUND. Så, igjen, ville du informere brukeren og avslutte.
Dette er, til slutt, en variant av den samme tilnærmingen, bare denne gangen vi sjekker forutsetningene etter at vi gjør noe, heller enn før. Fordelen er at hver funksjon kan sjekke sine egne forutsetninger, og i tilfelle av Windows API, er alle mulige returverdier ganske godt dokumentert, så med disiplinerte skriftlig, er det faktisk mulig å håndtere alle forhold, forutsatt at den som skrev den API tok alle sine forutsetninger i betraktning. Kode skrevet med denne tilnærmingen vil se omtrent slik ut (Nei, dette er ikke gyldig pascal, mine unnskyldninger til puristene):
ErrCode: = AssignFile (F, 'SomeFile.Txt'); hvis ErrCode = FILE_NOT_FOUND thenbegin WriteLn ( 'Fil ikke funnet'); Exit; ende; ErrCode: = ResetFile (F), hvis ErrCode = FILE_NO_ACCESS thenbegin WriteLn ('. Du don''t har tilgang til å gjøre det'); Exit; end annet hvis ErrCode = FILE_ALREADY_OPEN thenbegin WriteLn ('Noen andre leser filen'); Exit; end; ErrCode: = ReadLn (F, S); //La oss anta at dette betyr lese fra F til Sif ErrCode = NOT_ENOUGH_TEXT thenbegin WriteLn ('Not Enough Tekst'); Exit; ende; CloseFile (F),
Du får ideen. Det kan være mye verre, men vårt program har fått virkelig kompleks veldig raskt, og alt for å imøtekomme ting som normalt ikke skje.
Så, noen de siste par tiårene hatt en ny idé. Hvorfor ikke lage en kontrollstruktur spesielt for spesielle situasjoner? Denne nye kunne kontrollere strukturen ville tillate oss å definere hva som skal skje på vanlig måte, og deretter definere hva som skal skje hvis noe går galt. Dette er kjent som " unntakshåndtering ".
Grunnleggende ideen bak et unntak er at vi antar at den normale flyten kontroll kommer til å skje. Hvis den ikke gjør det, vi umiddelbart stoppe kjøringen uansett hvor vi er, og gå ut av gjeldende funksjon. Vi deretter avslutte funksjonen som kalles den funksjonen, og så videre, inntil, når vi et unntak handler, som er en blokk med kode som kjøres bare når en eksepsjonell tilstand eller hendelse finner sted. Hvis den normale flyten av henrettelsen blir fulgt, er unntaksbehandlerne ignorert.
I Delphi, er den normale flyten av henrettelse i et forsøk blokk, og unntaket behandleren er i en unntatt blokk. Her er et enkelt eksempel:
prøve AssignFIle (F, 'SomeFile.txt'); ResetFile (F); S: = Readln (F); CloseFile (F), unntatt WriteLn ('Det oppstod en feil'); end;
Dette er renere, og det gjør at vi kan tydelig se hva koden vi forventer å bli henrettet normalt, og hva koden skal bli henrettet når noe rart skjer (ikke liker at siste eksempelet ... grøss).
Selvfølgelig, det ville være hyggelig å kunne fortelle brukeren nøyaktig hva feilen oppstod. Avvikshåndtering gjør dette til en lek også. Siden avvikshåndtering utviklet hånd-i-hånd med objektorientert programmering, det aller meste kalt unntaksobjekter unnfanget. Unntaket objekt opprettes automatisk når et unntak er hevet. Hvis vi ønsker å bruke unntaksobjekt, utvider vi try..except syntaks som dette:
prøve AssignFile (F, 'SomeFile.txt'); ResetFile (F); S: = Readln (F); CloseFile (F), bortsett fra på E: Exception gjøre WriteLn (E.Message); end;
Du skjønner, har hver unntak en melding eiendom som gir noen korte nyttig informasjon om den spesifikke unntak. Det kan inneholde strengen " File Not Found, " eller " Fil allerede er i bruk, " eller noe annet som vi ønsker å fortelle brukeren.
Det finnes forskjellige typer unntak, og vi kan dra nytte av det også. Kanskje vi ønsker å gjøre noe spesielt når et visst unntak skjer. Kanskje vi ønsker å pipe hvis filen ikke er funnet:
prøve AssignFile (F, 'SomeFile.txt'); ResetFile (F); S: = REadln (F); CloseFIle (F), bortsett fra på E: FileNotFound gjøre Beep; på E: Exception gjøre WriteLn (E.Message); end;
Merk at når vi håndtere flere unntak, må den mest spesifikke unntak gå først. Dette er fordi unntakene er polymorfe -. Det er, er Unntak HVER unntak, og EFileNotFound er et unntak, så hvis Unntak håndteres først, EFileNotFound vil aldri bli håndtert
Et problem med denne mekanismen er at vi er fortsatt ikke sikker hva unntak en bestemt funksjon eller prosedyre kan øke. Noen språk eller utviklingsverktøy har en mekanisme for å hjelpe deg å vite hva som kan bli hevet. En C # IDE, for eksempel, vil gi deg et lite hint vindu for å fortelle deg hva unntakene du bør håndtere når du bruker en funksjon. Java er beryktet (og hatet av mange) for det faktum at det håndhever avvikshåndtering med terrorist iver. Koden vil ikke engang kompilere hvis du ikke håndtere unntakene at det ønsker at du skal, selv om du vet at disse unntakene ikke kommer til å skje, enten fordi du har kontroll over den løpende miljø, eller koden har allerede prechecked tilstanden og sørget for at unntaket ikke kan muligens bli kastet. Java vil håndheve sin kode stil til bokstav og tøddel, enten du liker det eller ikke.
Dessverre finnes det ingen slike verktøy for Delphi. Som jeg skriver dette, jeg begynner å tro det kan være en god ting å legge til Castalia. Jeg må se på det
. Puh! Det var tre og en halv sider av Microsoft Word, bare for å forstå hva et unntak er. Nå for morsomme ting:
Castalia kan hjelpe deg å skrive både normal koden og ditt avvikshåndtering kode. Castalia sin kode maler definere en Trye mal som automatisk oppretter en try..except blokk for deg og setter opp inngangspunkter, slik at du kan riktig opprette koden din. Dette vil spare deg flere tastetrykk og mer tid enn du innser!
Castalia største refactoring verktøy gir en automatisert surround med ... refactoring som vil sette en try..except blokken rundt koden. Bare merk normal flyt kontrollkoden, høyreklikk på redaktøren (eller trykk Shift + Ctrl + R), og velg riktig element fra refactoring menyen. Koden vil bli endret automatisk.
Denne uken har vi lært hva try..except blokken er for og hvor den kom fra (og hvorfor det er den beste feilhåndtering mekanismen ennå). Vi har også lært hvordan Castalia kan gjøre bruk av dette kraftige kontrollstruktur for å skrive mer robust og brukervennlig kode.
For mer informasjon om Castalia sin kode maler, klikk her.
For mer informasjon om Castalia automatiserte refactorings, Klikk her
Å kjøpe Castalia akkurat nå fordi denne artikkelen var det beste du noensinne har lest, klikk her, kan du klikke her for å lese en mye bedre bok. Anmeldelser



Previous:
Next Page: