【问题标题】:How can I pass a slice as a variadic input?如何将切片作为可变参数输入?
【发布时间】:2014-07-06 14:22:58
【问题描述】:

我有一个函数func more(... t)。我想知道是否可以使用切片来填充参数列表 ...

我正在尝试解决以下程序。基本上是为了模仿一个普通的shell,它以字符串的形式接收命令。 Command 函数需要一个参数“列表”,我不知道如何将字符串转换为这样的列表

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

【问题讨论】:

    标签: go


    【解决方案1】:

    The Go Programming Language Specification

    Passing arguments to ... parameters

    如果 f 是具有最终参数类型 ...T 的可变参数,则在 函数的实参等价于 []T 类型的形参。在 每次调用 f,传递给最终参数的参数都是一个新的 []T 类型的切片,其连续元素是实际参数, 其中所有都必须可分配给类型 T。切片的长度是 因此绑定到最终参数的参数数量可能 每个呼叫站点都不同。


    Package exec

    func Command

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

    命令返回 Cmd 结构以执行命名程序 给定参数。

    返回的 Cmd 的 Args 字段由命令名构成 后跟 arg 的元素,所以 arg 不应包含命令 自己命名。例如,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
    

    【讨论】:

      【解决方案2】:

      可以从flag package Args() function 检索命令参数列表。然后,您可以使用可变输入样式 (func(input...)) 将其传递给函数

      来自the Spec

      如果 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
      }
      

      更多详情请见The Go spec

      Playground

      【讨论】:

        【解决方案3】:

        func Command

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

        命令返回 Cmd 结构以使用给定的参数执行命名程序。

        因此,您必须提取位于 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 的切片 slice[1:]... 不会失败,它会被视为 []...。如果您不知道将提前使用的命令,这很有用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-17
        • 1970-01-01
        • 2016-03-26
        • 2018-08-31
        • 2016-10-27
        • 1970-01-01
        • 2018-11-23
        相关资源
        最近更新 更多