为什么在Go语言中添加一个Error()方法会改变程序的行为?

huangapple go评论82阅读模式
英文:

Why does adding an Error() method change program behavior in Go?

问题

下面的程序打印出"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语言规范解释这种行为的指引,将不胜感激。

英文:

The program below prints "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)
}

Interestingly, when I uncomment the Error() method, the program no longer prints "2.5"

Question:
Why does adding an Error() method change program behavior? Pointers to the Go language specification explaining this behavior would be much appreciated.

答案1

得分: 5

myFloat64实现了error接口:

type error interface {
  Error() string
}

fmt.Println()将把a视为一个error值,并通过调用a.Error()打印错误消息,该方法执行fmt.Sprintf("Error with %v", f)。但是,Sprintf的行为与Println类似,它也将f视为一个error值并调用Error()。这种递归无限地进行下去,导致堆栈溢出。

英文:

myFloat64 implements the error interface:

type error interface {
  Error() string
}

fmt.Println() will consider a as an error value, and print the error message by calling a.Error(), which executes fmt.Sprintf("Error with %v", f). But Sprintf behaves just like Println, it also considers f as an error value and calls Error(). This recursion goes infinitely and causes stack overflow.

huangapple
  • 本文由 发表于 2021年12月29日 15:06:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/70516154.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定