Reputation: 12429
I am working through the golang tour and I am stuck in one of the exercises. I am not sure why the following does not work for a String() function:
type IPAddr [4]byte
func (addr IPAddr) String() string {
return string(addr[0]) + "." + string(addr[1]) + "." + string(addr[2]) + "." + string(addr[3])
}
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)
}
}
Output:
loopback: ...
googleDNS: ...
Granted that using fmt.Sprintf()
would be a nicer solution, but I'm not sure I understand why that function doesn't work.
Upvotes: 2
Views: 437
Reputation: 8706
A more efficient implementation with less temporary memory allocations:
func (addr IPAddr) String() string {
buf := make([]byte, 0, 3+1+3+1+3+1+3)
return string(
strconv.AppendInt(
append(
strconv.AppendInt(
append(
strconv.AppendInt(
append(
strconv.AppendInt(buf,
int64(addr[0]), 10), '.'),
int64(addr[1]), 10), '.'),
int64(addr[2]), 10), '.'),
int64(addr[3]), 10))
}
Upvotes: 0
Reputation: 5886
What's happening there is that you're passing the byte e.g. 127 directly into string and expecting it to represent that byte as the integer 127 before converting it into a string. Instead what it's doing is interpreting it as a character with the byte value 127.
Instead you should convert that byte value into an integer, then use the strconv
library to format it as a string.
package main
import (
"fmt"
"strconv"
)
type IPAddr [4]byte
func (addr IPAddr) String() string {
return strconv.Itoa(int(addr[0])) + "." + strconv.Itoa(int(addr[1])) + "." + strconv.Itoa(int(addr[2])) + "." + strconv.Itoa(int(addr[3]))
}
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)
}
}
Output:
loopback: 127.0.0.1
googleDNS: 8.8.8.8
Upvotes: 7