3 ms·
What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.
by pcwalton 9y ago
What's the use case for function scoped defer? I have never once needed function scoped RAII in C++ or any other language.
- br1 9y agoCollecting tasks from all iterations to await before returning.
- barsonme 9y agoIt's not terribly uncommon for larger functions to do something like func someSQLStuff() { tx, err := createTx() defer func() { if err != nil { tx.Rollback() log(err) } else { tx.Commit() } }() rows, err = tx.QueryContext( ... ) // more SQL } Basically, function-scoped cleanup. Like closing opened files.
- Groxx 9y agoI have a comment at a higher level with a broader example, but for Go at least this is somewhat common: func f(i interface{}) { if closable, ok := i.(closable); ok { defer closable.close() } // do stuff with i, maybe other casts, etc } There aren't many nice options for "if I can call X, defer a call to X" aside from shoving it into an `if`, where it'd be captured by that scope. I mean, you could do something like deferrable := func(){} if closable { deferrable = closable.close } defer deferrable() but imagine doing that every time. It'd work, sure, but it'd also be more annoying.
- pcwalton 9y agoCouldn't you do: func closeIfNecessary(object interface{}) { closable, needsClosing := object.(closable) if needsClosing { closable.close() } } And then just do: func f(i interface{}) { defer closeIfNecessary(i) ... } Doing it this way also saves you boilerplate by factoring the downcast out into a separate function.
- Groxx 9y agoAs long as you can always call .close() regardless of the code below, yep - that'd work, and is definitely more readable. If you can't call it unless [some other conditions], it goes back to the same kind of problem though. "closable" may not be a good choice on my part, as they're often called unconditionally.