On Wed, 19 Oct 2016 15:35:40 -0700 (PDT)
andrew.sm...@miracl.com wrote:

[...]
> Im considering a scheme where I push every CString onto an
> implementation of a stack, and then call defer once. Im sure some
> people might think it overkill... Kinda like this :
> 
> func Outer(arg1 string, arg2 string, arg3 string, arg4 string) Return
> { stack := NewStack()
> defer stack.Destroy()
> return wrapReturn(
> C.inner(
> NewStackCString(arg1, stack).p,
> NewStackCString(arg2, stack).p,
> NewStackCString(arg3, stack).p,
> NewStackCString(arg4, stack).p))
> }
[...]

I think something like this should work in Go almost unmodified --
just you won't have a system-provided "defer list", will have a single
deferred execution of stack.Destroy() and have your own implementation
of that stack type.

Something like this:

----------------8<----------------
    package main
    
    import "fmt"
    
    type dtor func()
    
    type cleanup struct {
        dts []dtor
    }
    
    func (c *cleanup) Add(d dtor) {
        c.dts = append(c.dts, d)
    }
    
    func (c *cleanup) Cleanup() {
        for _, f := range c.dts {
                f()
        }
    }
    
    type Foo struct{}
    
    func (f Foo) Close() {
        fmt.Println("Foo.Close()")
    }
    
    type Bar struct{}
    
    func (b Bar) CFree() {
        fmt.Println("Bar.CFree()")
    }
    
    func foo() {
        var dts cleanup
        defer dts.Cleanup()
    
        foo := Foo{}
        dts.Add(foo.Close)
    
        bar := Bar{}
        dts.Add(bar.CFree)
    }
    
    func main() {
        foo()
    }
----------------8<----------------

(Playground link: https://play.golang.org/p/TqCfBfZb_X).


BTW I found myself doing something much like this in some of my C#
projects to avoid nesting hell of

  using (...acquire resource...) {
    using (...acquire resource...) {
      ...etc ad nauseum
  }

whereas you have a stack-like data type which implements IDisposable,
and you just have a single using() { ... } block for it inside which
you add particular resources to be destroyed to that instance, and at
the end of the block it's told to destroy itself and then it destroys
whatever resources have been added to it.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to