108

私はいくつかのコードを書いていますが、引数をキャッチして渡す必要がありますfmt.Println
(引数をスペースで区切って改行を続けるというデフォルトの動作が必要です)。ただし、かかります[]interface {}が、をflag.Args()返します[]string
コード例は次のとおりです。

package main

import (
    "fmt"
    "flag"
)

func main() {
    flag.Parse()
    fmt.Println(flag.Args()...)
}

これにより、次のエラーが返されます。

./example.go:10: cannot use args (type []string) as type []interface {} in function argument

これはバグですか?配列fmt.Printlnを取るべきではありませんか?ちなみに、私もこれをやろうとしました:

var args = []interface{}(flag.Args())

しかし、次のエラーが表示されます。

cannot convert flag.Args() (type []string) to type []interface {}

これを回避する「Go」方法はありますか?

4

7 に答える 7

130

これはバグではありません。fmt.Println()タイプが必要[]interface{}です。つまり、interface{}「任意のスライス」ではなく、値のスライスでなければなりません。スライスを変換するには、各要素をループしてコピーする必要があります。

old := flag.Args()
new := make([]interface{}, len(old))
for i, v := range old {
    new[i] = v
}
fmt.Println(new...)

スライスを使用できない理由は、 a[]stringと a の間の変換に[]interface{}はメモリ レイアウトを変更する必要があり、O(n) 時間で発生するためです。型を に変換するにinterface{}は O(1) 時間が必要です。これを for ループが不要にした場合でも、コンパイラはそれを挿入する必要があります。

于 2012-10-20T16:42:51.620 に答える
11

印刷したい文字列のスライスのみの場合は、変換を回避して、結合することでまったく同じ出力を得ることができます。

package main

import (
    "fmt"
    "flag"
    "strings"
)

func main() {
    flag.Parse()
    s := strings.Join(flag.Args(), " ")
    fmt.Println(s)
}
于 2015-12-19T16:06:35.007 に答える