【问题标题】:Function executing itself without being called函数自己执行而不被调用
【发布时间】:2018-12-19 00:20:01
【问题描述】:

我昨天在 Tour of Go 网站上开始学习围棋,我认为我对所有内容都很了解;

但后来我对纵梁练习完全感到困惑:https://tour.golang.org/methods/18

所以我搜索了一个解决方案,看看我做错了什么,我发现了这个:

package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.

func (i IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", i[0], i[1], i[2], i[3])   

 }

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

输出如下:

loopback: 127.0.0.1
googleDNS: 8.8.8.8

这让我完全糊涂了;

为什么函数会自动激活?不应该是:主函数内的 i.String() 吗?

为什么 fmt.Printf 在屏幕上什么也没有显示?

或者 fmt.Printf 因为 String() 改变了值而返回?

如果问题令人困惑,我很抱歉,但有人可以向我解释一下吗?

【问题讨论】:

    标签: go


    【解决方案1】:

    如果您查看 the previous page in the tutorial,您会看到 Stringer 是在 fmt 包中定义的 an interface。实现String()方法automatically使得IPAddr实现了这个接口。

    fmt.Printf 函数检查其参数是否实现了Stringer 接口。既然它现在这样做了,它会在需要弄清楚如何显示IPAddress 时调用String 方法(您可以通过使用%v 以外的格式说明符来更改此行为,但这超出了问题的范围)。

    fmt.Printf 调用显示了一些东西;它显示了线条

    loopback: 127.0.0.1
    googleDNS: 8.8.8.8
    

    这并没有改变它们的价值或任何东西;它只是调用了String 方法来弄清楚如何写下IPAddr,并以这种方式写下来。

    【讨论】:

    • 非常感谢!我猜我没注意页面,但是,你能向我解释一下 %v 的事情吗?
    • 当然。 rules for how Printf converts values to strings 有点复杂,但一般来说,如果你说%v,它会尝试制作一个人类可读的表示,如果你说%#v 会打印你需要编写的内容以获得该值作为Go中的变量,您可以使用v以外的各种字符,例如%x,以各种专用格式打印(我不确定这对用户定义的类型有什么作用),%%会给你一个实际的百分号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    相关资源
    最近更新 更多