1. 9
  1.  

  2. 1

    That defer thing is really weird, and quite counterintuitive. Any rationale? Some sort of symmetry with go?

    1. 4

      I would have thought of it as plenty intuitive, to be honest, but maybe that’s just my background speaking. As with most function calls, arguments are evaluated before the call happens; in this case, the call gets deferred, but it still seems to make sense that args are evaluated immediately in order to defer the call. (I’d expect defer x(1 + 1) to evaluate 1 + 1 = 2 immediately, for instance.)

      1. 1

        Well, it looks a lot like a simpler syntax version of “finally” which doesn’t evaluate anything until it runs. I suppose it depends on which construct you map it too. If I map it to RAII, then it makes a lot more sense. But my “feels” tell me it’s like finally.

        1. 2

          The “finally” part is the deferred function’s body. One of the idioms with defer is to use argument to capture values rather than closing over names if you need to use defer on e.g. the for variable:

          for _, thing := range stuff {
            defer func(theThing Thing) {
              theThing.FinishIt()
            }(thing)
            thing.ProcessIt()
          }
          

          Whatever are the arguments for deferred function, they exist when you invoke defer, and they may not be reachable anymore (and might have been already GCed) by the time deferred function runs. And if you need to evaluate the arguments by the time deferred function runs, you can just wrap it in another function and close over the values you need (should work, unless you’ll be using a loop variable - you’ll probably get the last value only, because it will be evaluated after the loop has finished):

          defer func() {
            closeMyNetworkConnection(networkConn, determineHowConnShouldBeClosed())
          }()
          
    2. 1

      All of these things are covered in the Go Tour.