Cannot convert []string to []interface {}
This is not a bug. fmt.Println()
requires a []interface{}
type. That means, it must be a slice of interface{}
values and not "any slice". In order to convert the slice, you will need to loop over and copy each element.
old := flag.Args()
new := make([]interface{}, len(old))
for i, v := range old {
new[i] = v
}
fmt.Println(new...)
The reason you can't use any slice is that conversion between a []string
and a []interface{}
requires the memory layout to be changed and happens in O(n) time. Converting a type to an interface{}
requires O(1) time. If they made this for loop unnecessary, the compiler would still need to insert it.
In this case, a type conversion is unnecessary. Simply pass the flag.Args()
value to fmt.Println
.
Question:
Cannot convert []string to []interface {}
I'm writing some code, and I need it to catch the arguments and pass them through fmt.Println (I want its default behaviour, to write arguments separated by spaces and followed by a newline).
Here's the code example:
package main import ( "fmt" "flag" ) func main() { flag.Parse() fmt.Println(flag.Args()...) }
Package flag
import "flag"
func Args
func Args() []string
Args
returns the non-flag command-line arguments.
Package fmt
import "fmt"
func Println
func Println(a ...interface{}) (n int, err error)
Println
formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.
In this case, a type conversion is unnecessary. Simply pass the flag.Args()
value to fmt.Println
, which uses reflection to interpret the value as type []string
. Package reflect
implements run-time reflection, allowing a program to manipulate objects with arbitrary types. For example,
args.go
:
package main
import (
"flag"
"fmt"
)
func main() {
flag.Parse()
fmt.Println(flag.Args())
}
Output:
$ go build args.go
$ ./args arg0 arg1
[arg0 arg1]
$
If it's only a slice of strings you want to print, you can avoid conversion and get the exact same output by joining:
package main
import (
"fmt"
"flag"
"strings"
)
func main() {
flag.Parse()
s := strings.Join(flag.Args(), " ")
fmt.Println(s)
}