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

Viewed 72

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 Answers

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.

Related