Understanding the Strange Behavior of Interface Types in Go
In Go, interfaces define contracts that allow different types to behave similarly. However, there can be unexpected behavior when using interfaces with custom methods, as illustrated in the following example:
type T int func (t T) Error() string { return "bad error" } func main() { var v interface{} = T(5) fmt.Println(v) // Output: "bad error" }
Why does the above code not print the value of T(5) as expected? The reason lies in the way Go interacts with interfaces and their methods.
fmt.Println and the %v Formatter
The fmt.Println function uses the %v formatter to print the value of an interface. According to the documentation, if an operand implements the error interface, its Error method will be invoked to convert the object to a string.
In our case, T implements the error interface with a custom Error method that returns "bad error". When fmt.Println is called with v (an interface value of type T), it uses the Error method to generate its string representation. This is why we see "bad error" as the output instead of the value 5.
Custom Formatting
To avoid this unexpected behavior, you can use custom formatting by passing a format string to fmt.Printf. For example:
fmt.Printf("%d", v) // Output: "5"
This explicitly instructs fmt.Printf to print the value of v as a decimal integer, overriding the default %v formatting.
Conclusion
Understanding how Go interacts with interfaces and the %v formatter is crucial for avoiding unexpected behavior when dealing with custom methods and formatting. Be aware that the Error method of an error interface can influence the result of fmt.Println, and use custom formatting when necessary to ensure the desired output.
The above is the detailed content of Why Does `fmt.Println` Print 'bad error' Instead of 5 When Using a Go Interface with a Custom `Error` Method?. For more information, please follow other related articles on the PHP Chinese website!