Hacker News new | ask | show | jobs
by Groxx 3096 days ago
I 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.
1 comments

Couldn'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.
As 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.