How can I pass a slice as a variadic input?
GoGo Problem Overview
I have a function func more(... t)
. I'm wondering if it's possible to use a slice to populate a list of arguments ...
.
I'm trying to solve the following program. Basically to mimic a normal shell which receives the command as a string. Command function requires a "list" of arguments and I don't see how I can convert a string into a such list
import "os/exec"
import "strings"
func main(){
plainCommand := "echo hello world"
sliceA := strings.Fields(plainCommand)
cmd := exec.Command(sliceA)
}
Go Solutions
Solution 1 - Go
> The Go Programming Language Specification > > Passing arguments to ... parameters > > If f is variadic with final parameter type ...T, then within the > function the argument is equivalent to a parameter of type []T. At > each call of f, the argument passed to the final parameter is a new > slice of type []T whose successive elements are the actual arguments, > which all must be assignable to the type T. The length of the slice is > therefore the number of arguments bound to the final parameter and may > differ for each call site.
> Package exec > > func Command > > func Command(name string, arg ...string) *Cmd > > Command returns the Cmd struct to execute the named program with the > given arguments. > > The returned Cmd's Args field is constructed from the command name > followed by the elements of arg, so arg should not include the command > name itself. For example, Command("echo", "hello")
For example,
package main
import (
"fmt"
"os/exec"
)
func main() {
name := "echo"
args := []string{"hello", "world"}
cmd := exec.Command(name, args...)
out, err := cmd.Output()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(out))
}
Output:
hello world
Solution 2 - Go
A list of command arguments can be retrieved from the flag package Args()
function. You can then pass this to a function using the variadic input style (func(input...)
)
From the Spec:
> If f is variadic with final parameter type ...T, then within the function the argument is equivalent to a parameter of type []T. At each call of f, the argument passed to the final parameter is a new slice of type []T whose successive elements are the actual arguments, which all must be assignable to the type T.
Example:
package main
import "fmt"
func echo(strings ...string) {
for _, s := range strings {
fmt.Println(s)
}
}
func main() {
strings := []string{"a", "b", "c"}
echo(strings...) // Treat input to function as variadic
}
See The Go spec for more details.
Solution 3 - Go
>func Command > func Command(name string, arg ...string) *Cmd
>Command returns the Cmd struct to execute the named program with the given arguments.
So you have to extract the command which is found at sliceA[0]
and then pass all the arguments with a variadic but removing the command sliceA[1:]...
.
import "os/exec"
import "strings"
func main(){
plainCommand := "echo hello world"
sliceA := strings.Fields(plainCommand)
cmd := exec.Command(sliceA[0], sliceA[1:]...)
}