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

huangapple go评论83阅读模式
英文:

How can I pass a slice as a variadic input?

问题

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

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

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

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

答案1

得分: 143

《Go编程语言规范》

将参数传递给...参数

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

《exec包》

func Command

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

Command返回用给定参数执行命名程序的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

英文:

> 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

答案2

得分: 22

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

根据规范

如果最后一个参数类型为...T的可变参数函数f,在函数内部,该参数等同于类型为[]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...) // 将函数的输入视为可变参数
}

更多详细信息请参阅Go规范

Playground

英文:

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

答案3

得分: 8

func Command

函数Command返回一个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:]...)
}
英文:

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

huangapple
  • 本文由 发表于 2014年5月19日 00:02:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/23723955.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定