First, when I run: main package
import "fmt"
type IPAddr [4]byte // TODO: Add a "String() string" method to IPAddr. func (a IPAddr) String() string { return fmt.Sprintf("%d.%d.%d.%d", a...) } func main() { addrs := map[string]IPAddr{ "loopback": {127, 0, 0, 1}, "googleDNS": {8, 8, 8, 8}, } for n, a := range addrs { fmt.Printf("%v: %v\n", n, a) } }
Error:
prog.go: 9: cannot use (type IPAddr) as type [] interface {} in argument fmt.Sprintf
but not
cannot use [] a string literal (type [] string) as type [] interface {} in the argument fmt.Sprintf
So, I think something went out of sync when copying and pasting.
type IPAddr [4]byte does not define a string, so the error message in the question is misleading.
This is a [4]byte , a completely different type (in terms of the Go language type) of the string. This is not []byte .
Otherwise, type IPAddr [4]byte satisfies the interface, for example, implements String (), which can use fmt.Sprintf, because the IPAddr String () method does not compile.
You can try to convert [4]byte to string, but this string(a) conversion is not legal. Worse, four byte values will be treated as character codes and will not be converted to the symbolic representation of four small integer values. It is very likely that some byte values of IPAddr may be invalid UTF-8, which would be even stranger if the program tried to print it.
As explained in other answers,
return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
returns the string value of IPAddr in the format you are aiming for.
Once func (a IPAddr) String() string valid, it works; IPAddr implements the fmt.Stringer interface.
Then %v at
fmt.Printf("%v: %v\n", n, a)
can be replaced by %s in
fmt.Printf("%s: %s\n", n, a)
because the fmt output methods have an implementation of String ().
I prefer %s to %v because it signals that the program does not rely on the "default representation of Go" (ie, for this array [127 0 0 1] ) and that the type implements String ().