为了账号安全,请及时绑定邮箱和手机立即绑定

不使用 Sprintf 的 Stringer 实现

不使用 Sprintf 的 Stringer 实现

Go
白板的微信 2021-09-27 20:58:55
我正在完成 golang 之旅,但被困在其中一项练习中。我不确定为什么以下不适用于 String() 函数:type IPAddr [4]bytefunc (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()会是一个更好的解决方案,但我不确定我是否理解为什么该功能不起作用。
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

发生的事情是您将字节(例如 127)直接传递到字符串中,并期望它在将其转换为字符串之前将该字节表示为整数 127。相反,它正在做的是将其解释为字节值为 127 的字符。


相反,您应该将该字节值转换为整数,然后使用strconv库将其格式化为字符串。


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)

    }

}

输出:


loopback: 127.0.0.1

googleDNS: 8.8.8.8


查看完整回答
反对 回复 2021-09-27
?
慕斯王

TA贡献1864条经验 获得超2个赞

具有更少临时内存分配的更有效的实现:


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))

}


查看完整回答
反对 回复 2021-09-27
  • 2 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信