有谁知道为什么下面的两个Golang代码片段会得到不同的结果吗?在这两个应用程序中,String()方法构造了一个表示IPAddr中各个字节的字符串切片,然后使用strings.Join将它们连接成一个四点IP地址格式。但是,这两个应用程序对相同的输入产生不同的结果。注意这两个应用程序如何构造要在String()中连接的字符串切片的差异for循环中的方法。
应用1
package main
import (
"fmt"
"strconv"
"strings"
)
type IPAddr [4]byte
func (ip IPAddr) String() string {
s := make([]string, len(ip))
for i := range ip {
s[i] = strconv.Itoa(int(ip[i]))
}
return strings.Join(s, ".")
}
func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip.String())
}
}
// Result:
// loopback: 127.0.0.1
// googleDNS: 8.8.8.8
字符集
应用二:
// Application 2
package main
import (
"fmt"
"strconv"
"strings"
)
type IPAddr [4]byte
func (ip IPAddr) String() string {
s := make([]string, len(ip))
for _, val := range ip {
s = append(s, strconv.Itoa(int(val)))
}
return strings.Join(s, ".")
}
func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip.String())
}
}
// Result:
// loopback: ....127.0.0.1
// googleDNS: ....8.8.8.8
型
3条答案
按热度按时间ffvjumwh1#
在第二个
String
方法中...字符集
.你从一个4字符串的切片开始。也就是说,在循环之前,
s
是{"", "", "", ""}
。对于循环的每次迭代,你都要向切片追加一个新项。如果我们在循环中添加一个fmt.Printf
语句,如下所示:型
我们看到输出:
型
当你在
.
上连接这段字符串时,你连接了8个项目。前四个是空的,这就是为什么你的结果以....
开头。如果你从一个空切片开始,你会得到你期望的结果:
型
7kjnsjlb2#
第一个片段创建
s
,然后用字节的整数值的字符串表示来填充它的每个元素。字符集
第二个代码片段也用
len(ip)
创建了s
,但是它没有设置s[:len(ip)]
中的一个,而是将 * 追加到那些原始的len(ip)
上,导致s
是2xlen(ip)
元素长,前半部分未设置。字符串的零值是""
,所以在开头有额外的点。型
The alternative to method one using
append
is to set the capacity, not the length, inmake
.型
3df52oht3#
在第二种方法中
字符集
你首先是
making
一个长度为len(ip)
的数组,然后在它的末尾追加元素。所以它最终的长度为2*len(ip)
。