【发布时间】:2022-01-27 15:19:53
【问题描述】:
下面的程序打印“2.5”
package main
import (
"fmt"
)
type myFloat64 float64
// func (f myFloat64) Error() string {
// return fmt.Sprintf("Error with %v", f)
// }
func main() {
var a myFloat64 = myFloat64(2.5)
fmt.Printf("%v\n", a)
}
有趣的是,当我取消注释 Error() 方法时,程序不再打印“2.5”
问题:
为什么添加Error() 方法会改变程序行为?指向解释此行为的 Go 语言规范的指针将不胜感激。
【问题讨论】:
-
我从一个至少部分多余的答案开始(因此关闭了问题),但请查看this version on the Go playground。请注意,我将
fmt.Sprintf更改为使用%f;如果您将%v留在此处并运行它,您将看到无限递归。 -
因为 %v 调用 Error 再次使用 %v 来格式化调用 Error 的值,而再次使用 %v 格式化值又调用 Error .... 你得到了一个无限循环,它产生了一个 SO .
-
我觉得这个问题应该向其他提出相同问题的人开放。答案,OP,是因为当你将 Error 方法添加到你的浮点数时,你正在创建一个错误类型。您可以在此处查看规范:go.dev/ref/spec#Errors 然后,当您调用 Printf 时,代码会在打印期间调用该方法,在此处定义:cs.opensource.google/go/go/+/refs/tags/go1.17.5:src/fmt/…
-
@Jorge,是的,你的把戏有效,但主要问题是 %v。这是一个方便的工具来格式化你不知道它是什么的东西。但如果你知道它是什么:使用适合你的类型的动词。
-
我希望 Go 操场告诉用户堆栈溢出。调试会更容易。
标签: go