Very Nice find, I did not know that idiom before. I will try to break it down.
First We have exec.Cmd
type exec.Cmd struct { ... }
*Cmd
has 3 many methods including stdin
stdout
stderr
func (c *Cmd) stdin() (f *os.File, err error) {...}
func (c *Cmd) stdout() (f *os.File, err error) {...}
func (c *Cmd) stderr() (f *os.File, err error) {...}
Now I want to call all these functions and do the same set of operations on each of them but I don't want to create another method because there are too many shared variable to pass by arguments.
The first solution would be to just copy / paste the code 3 times. not nice.
The second is to loop over an array of Functors. The Functor type would be func(c*Cmd)(f *os.File, err error)
so we declare it as
type F (c *Cmd) (f *os.File, err error)
now we can create the array of functors. But how to select a *Cmd
method ? simply using
(*Cmd).<name of method>
So it would be (*Cmd).stdin, (*Cmd.stdout), (*Cmd).stderr
and we can use them as An array
[]F{ (*Cmd).stdin, (*Cmd.stdout), (*Cmd).stderr }
we just need to call them now
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
fd, err := setupFd(c)
...
}
Hope this helps.