如何将切片作为可变参数输入传递?

136
我有一个函数func more(... t)。我想知道是否可以使用切片来填充参数列表...
我正在尝试解决以下问题。基本上是模拟普通shell,该shell将命令作为字符串接收。 Command函数需要一个参数“列表”,我不知道如何将字符串转换为这样的列表。
    import "os/exec"
    import "strings"
    func main(){
        plainCommand  := "echo hello world"
        sliceA := strings.Fields(plainCommand)
        cmd := exec.Command(sliceA)
    }
3个回答

144

Go编程语言规范

向...参数传递参数

如果函数f的最后一个参数类型为...T,则在函数内部,该参数等同于类型为[]T的参数。每次调用f时,传递给最后一个参数的参数是类型为[]T的新切片,其连续元素是实际参数,所有这些参数都必须可分配到类型T。因此,切片的长度是绑定到最后一个参数的参数数量,并且可能因每个调用站点而异。


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")


例如,
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))
}

输出:

hello world

23
可以从flag包的 Args() 函数中获取命令参数列表。然后,您可以使用可变输入样式(func(input...))将其传递给函数。

来自规范

如果f是最终参数类型为...T的可变参数,则在函数内部,该参数等效于类型[]T的参数。在每次调用f时,传递给最终参数的参数都是类型为[]T的新切片,其连续元素都是实际参数,所有这些参数都必须可分配给类型T。

例子:
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
}

查看Go规范获取更多详细信息。

Playground


8

func Command

func Command(name string, arg ...string) *Cmd

Command returns the Cmd struct to execute the named program with the given arguments.

因此,您需要提取在sliceA[0]处找到的命令,然后使用可变参数传递所有参数,但要删除命令sliceA[1:]...

import "os/exec"
import "strings"
func main(){
    plainCommand  := "echo hello world"
    sliceA := strings.Fields(plainCommand)
    cmd := exec.Command(sliceA[0], sliceA[1:]...)
}

1
这是一个非常好的解决方案。只是为了其他人而想知道 - 如果你有一个长度为1的切片 slice[1:]... 不会失败,而是被视为 []...。如果您事先不知道将要使用的命令,则非常有用。 - Anroca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接