3 ms·
I would disagree with defer being better than goto. Some people prefer it, but I think in a lot of ways it makes your control flow harder to see than just a few
by slaymaker1907 5y ago
I would disagree with defer being better than goto. Some people prefer it, but I think in a lot of ways it makes your control flow harder to see than just a few cleanup blocks at the end plus goto.
- Jtsummers 5y agoIt's a tradeoff. defer in Go is more like a try/finally statement in other languages, there's a guarantee that the deferred code will run even when there's a panic in the intervening code: handler = open(something); defer close(handler); // something causing a panic Should be the same as: handler = open(something); try { // something causing an exception } finally { close(handler); } This is not necessarily true of goto, you have to be more deliberate and disciplined (and discipline doesn't scale) to ensure that when your code hits an error you go to the cleanup section, if you miss even a single case and return early, you will not do the cleanup. Both defer and finally eliminate that potential error. The interesting thing (to me) about defer is that it promotes making explicit what's implicit in languages like C++ with RAII. In C++ with RAII, handler would be closed up at the end of the lexical scope but it's implicit, Go makes you explicitly state that you intend for it to be closed using a defer. But the defer, stylistically not by requirement, being near the initialization is, arguably, clearer than the goto or the finally statement. It's also less error prone, you can scan the function and see that someone left out a defer close(handler). But if you use a cleanup block at the end (either with try/finally or with gotos) you have to jump back and forth between the top and bottom of the function in order to see that everything has been cleaned up and in the correct order.
- slaymaker1907 5y agoThere is a huge difference in semantics with defer compared to RAII since defer is called at the end of the function while RAII is scope based. It's mostly the same except for if you want to use RAII in a loop.
- Jtsummers 5y agoThat's a difference based on the way Go implements defer, but not a principle of defer. A lexically scoped based defer is conceivable. That said, it's worth noting that difference in practice since Go is, as far as I know, the only mainstream language with defer as a major and commonly used construct.
- rightbyte 5y agoI guess Go's "defer" is from "rescue" in Alef (the Plan 9 language). Kinda the same guys. But "rescue" was only executed on signals.