... and defer
... and defer
Which “defer”? The go panic/defer pair is, while structured differently, functionally equivalent to exceptions.
try { ... }
catch (SomeException e) { ... }
catch (SomeOtherException e) { ... }
finally { /* cleanup code */ }
Pretty much every language with exceptions has an equivalent of that finally block, a portion of code guaranteed to run whether there is an exception or not.Defers in Go act like that finally block, but permit you to attach them at the point where the initialization they clean up was written. This can help with longer code blocks, but it's fundamentally the same as the above (with or without the catches). So if you use defer (the following is not really Go, but captures the idea):
function echo_file (filename) {
f = open(filename);
if nil == f { return; } // simple error handling, just don't do anything
defer close(f);
for line in f {
print(line);
}
}
function echo_file (filename) {
f = open(filename);
if nil == f { return; }
try {
for line in f {
print(line);
}
}
finally {
close(f);
}
}
The former is much shorter and clearer, especially for straightforward cleanup code, but is the same as the latter in what it does. Whether an exception or panic occurs during the read/print loop or not, the file will always be closed in both cases.exception handling mechanisms (try/except/finally) are idiomatic for that in languages with them (try/finally, particularly, because it assures cleanup whether or not an unhandled exception occurred); defer offers equivalent power with slightly different structure; you don't need both for any purpose either will do.