How can I pass a slice as a variadic input?

Go

Go 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.

Playground

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:]...)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThe user with no hatView Question on Stackoverflow
Solution 1 - GopeterSOView Answer on Stackoverflow
Solution 2 - GoIntermernetView Answer on Stackoverflow
Solution 3 - GoNathenapseView Answer on Stackoverflow