不使用 Sprintf 的 Stringer 实现

我正在完成 golang 之旅,但被困在其中一项练习中。我不确定为什么以下不适用于 String() 函数:


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)

    }

}

输出:


loopback: ...

googleDNS: ...

当然,使用fmt.Sprintf()会是一个更好的解决方案,但我不确定我是否理解为什么该功能不起作用。


白板的微信
浏览 186回答 2
2回答

斯蒂芬大帝

发生的事情是您将字节(例如 127)直接传递到字符串中,并期望它在将其转换为字符串之前将该字节表示为整数 127。相反,它正在做的是将其解释为字节值为 127 的字符。相反,您应该将该字节值转换为整数,然后使用strconv库将其格式化为字符串。package mainimport (    "fmt"    "strconv")type IPAddr [4]bytefunc (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)    }}输出:loopback: 127.0.0.1googleDNS: 8.8.8.8

慕斯王

具有更少临时内存分配的更有效的实现: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))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go