In your example, MyError2 does not have an Error() method so it is not called. From the fmt package docs (golang.org/pkg/fmt):
- 3. 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... rules apply: - 4. 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). MyError implements the error interface and MyError2 does not. On Fri, Jul 15, 2016 at 2:38 PM Thorsten von Eicken <t...@rightscale.com> wrote: > Yup, doesn't quite make sense to me that Error() is called if it's an > embedded struct and not when it's a struct field. See > https://play.golang.org/p/Vp6Y-RETWZ > > > On Friday, July 15, 2016 at 2:03:25 PM UTC-7, Thorsten von Eicken wrote: >> >> You're probably correct, see this: >> >> package main >> >> import ( >> "fmt" >> ) >> >> type MyError struct{ error } >> type MyError2 struct { >> foo int >> err error >> } >> >> func main() { >> err := MyError{} >> fmt.Printf("%%#v %#v\n", err) >> fmt.Printf("%%+v %+v\n", err) >> fmt.Printf("%%v %v\n", err) >> >> err2 := MyError2{} >> fmt.Printf("%%#v %#v\n", err2) >> fmt.Printf("%%+v %+v\n", err2) >> fmt.Printf("%%v %v\n", err2) >> >> var rr error >> fmt.Printf("%%#v %#v\n", rr) >> fmt.Printf("%%+v %+v\n", rr) >> fmt.Printf("%%v %v\n", rr) >> } >> >> %#v main.MyError{error:error(nil)} >> %+v %!v(PANIC=runtime error: invalid memory address or nil pointer >> dereference) >> %v %!v(PANIC=runtime error: invalid memory address or nil pointer >> dereference) >> %#v main.MyError2{foo:0, err:error(nil)} >> %+v {foo:0 err:<nil>} >> %v {0 <nil>} >> %#v <nil> >> %+v <nil> >> %v <nil> >> >> >> It's only if the error is embedded that it panics. >> Playground: https://play.golang.org/p/TeNVj96zxr >> >> On Friday, July 15, 2016 at 1:44:01 PM UTC-7, Matt Harden wrote: >>> >>> I think MyError has the Error method, which %v will use but %#v will >>> not. Then it panics because it's trying to call error(nil).Error(). >>> >>> On Fri, Jul 15, 2016, 13:22 Thorsten von Eicken <t...@rightscale.com> >>> wrote: >>> >>>> I was surprised to see Printf %v panic on a struct that %#v prints >>>> fine. Is this expected / intentional / as designed? >>>> >>>> Test case: >>>> package main >>>> >>>> import ( >>>> "fmt" >>>> ) >>>> >>>> type MyError struct{ error } >>>> >>>> func main() { >>>> err := MyError{} >>>> fmt.Printf("%%#v %#v\n", err) >>>> fmt.Printf("%%+v %+v\n", err) >>>> fmt.Printf("%%v %v\n", err) >>>> } >>>> >>>> Output: >>>> >>>> %#v main.MyError{error:error(nil)} >>>> %+v %!v(PANIC=runtime error: invalid memory address or nil pointer >>>> dereference) >>>> %v %!v(PANIC=runtime error: invalid memory address or nil pointer >>>> dereference) >>>> >>>> >>>> Playground: https://play.golang.org/p/B5FeWMryN0 >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "golang-nuts" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to golang-nuts...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.