Home > database >  Why return a func in Golang
Why return a func in Golang

Time:12-03

I was looking into golang contexts recently, and found that the WithCancel() is implemented in an interesting way.

func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
    if parent == nil {
        panic("cannot create context from nil parent")
    }
    c := newCancelCtx(parent)
    propagateCancel(parent, &c)
    return &c, func() { c.cancel(true, Canceled) }
}

WithCancel() returns a ctx, and also a func to cancel the very same context. Why is this done rather than introducing the .Cancel() as a func of the type itself, like

func (c *cancelCtx) Cancel() {
  c.cancel(true, Canceled)
} 

I understand using a func return type allows you to run a different func depending on runtime conditions, but there's no dynamic here - it's always the same func. Is this just because for the functional paradigm?

Reference: https://cs.opensource.google/go/go/ /master:src/context/context.go;l=232-239?q=context&ss=go/go

CodePudding user response:

Not all contexts are cancel-able. You could argue that for those that aren't, the Cancel() method could be a no-op.

But then you would always have to call Cancel() whenever you work with context.Context because you don't (can't) know whether it truly needs cancelling. This would be unnecessary in a lot of cases, would make code slower (cancel functions are usually called deferred) and would bloat the code.

Also, the power of cancelling a context is for its creator only. The creator may choose to share this responsibility by passing / sharing the cancel function, but if doesn't, sharing the context alone does not allow (should not allow) cancelling it. If Cancel() would be part of context.Context, this restriction could not be enforced. For details, see Cancel context from child.

Interfaces–especially those widely used–should be small and a minimum, not containing all, rarely useful things.

  •  Tags:  
  • go
  • Related