I've been looking through the tour for go, and I can't figure out why this happens.
When you have a Stringer
(String() string
), fmt
will use that method for printing to console. Like suggested in https://tour.golang.org/methods/6
However if you add Error() string
, this method gets called instead of String() string
.
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p *Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func (p *Person) Error() string {
return fmt.Sprintf("Failed")
}
func main() {
a := &Person{"Arthur Dent", 42}
z := &Person{"Zaphod Beeblebrox", 9001}
fmt.Println(a, z)
}
Results:
Failed Failed
I don't understand why fmt.Println
uses Error
instead of String
.
Simply because this is how it is implemented. An error
is more important in practice, so if the error
interface is implemented, that will be printed.
This is documented, read the package doc of fmt
:
Except when printed using the verbs %T and %p, special formatting considerations apply for operands that implement certain interfaces. In order of application:
If an operand implements the Formatter interface, it will be invoked. Formatter provides fine control of formatting.
If the %v verb is used with the # flag (%#v) and the operand implements the GoStringer interface, that will be invoked.
If the format (which is implicitly %v for Println etc.) is valid for a string (%s %q %v %x %X), the following two rules apply:
If an operand implements the error interface, the Error method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
So error
is 3rd on the list while String()
is only 4th.
The reason is simple: when fmt uses any of it's print functions, it does a type switch for each argument to determine how it should be printed, and in that type switch case error
appears just before case Stringer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With