围棋之旅:了解纵梁练习
Tour of Go: Understanding the stringers exercise
我在做 this exercise on stringers。
问题:使 IPAddr
类型的工具 fmt.Stringer
将地址打印为点分四边形。例如,IPAddr{1, 2, 3, 4}
应打印为 "1.2.3.4"
。
起始代码:
package main
import "fmt"
type IPAddr [4]byte
// TODO: Add a "String() string" method to IPAddr.
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)
}
}
这是我的代码:
func (addr IPAddr) String() string {
return fmt.Sprintf("%v.%v.%v.%v", addr[0], addr[1], addr[2], addr[3])
}
而且成功了!但我不明白为什么。我发现我不必明确定义 Stringer
接口,因为它包含在 fmt
中,但是我的代码在 main()
函数中的什么地方被使用了?它是否会自动 运行 它找到任何 IPAddr
类型的数据,这就是为什么地图在我不做任何事情的情况下被修改的原因?这是我的第一个基于编译器的语言(我知道一些 Python 和 JavaScript),所以我不知道这个概念是否与其他语言相似。
main
使用 fmt.Printf
打印 IP 地址,如果类型实现 Stringer
接口,则使用 String()
方法。由于您为该类型声明了 String() string
方法,因此 IPAddr
实现了 Stringer
接口。
您正在寻找的概念称为“Duck Typing”。无需将类型声明为实现接口。如果一个类型具有与接口相同的方法,则该类型实现该接口
我在做 this exercise on stringers。
问题:使 IPAddr
类型的工具 fmt.Stringer
将地址打印为点分四边形。例如,IPAddr{1, 2, 3, 4}
应打印为 "1.2.3.4"
。
起始代码:
package main
import "fmt"
type IPAddr [4]byte
// TODO: Add a "String() string" method to IPAddr.
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)
}
}
这是我的代码:
func (addr IPAddr) String() string {
return fmt.Sprintf("%v.%v.%v.%v", addr[0], addr[1], addr[2], addr[3])
}
而且成功了!但我不明白为什么。我发现我不必明确定义 Stringer
接口,因为它包含在 fmt
中,但是我的代码在 main()
函数中的什么地方被使用了?它是否会自动 运行 它找到任何 IPAddr
类型的数据,这就是为什么地图在我不做任何事情的情况下被修改的原因?这是我的第一个基于编译器的语言(我知道一些 Python 和 JavaScript),所以我不知道这个概念是否与其他语言相似。
main
使用 fmt.Printf
打印 IP 地址,如果类型实现 Stringer
接口,则使用 String()
方法。由于您为该类型声明了 String() string
方法,因此 IPAddr
实现了 Stringer
接口。
您正在寻找的概念称为“Duck Typing”。无需将类型声明为实现接口。如果一个类型具有与接口相同的方法,则该类型实现该接口