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.

Reply via email to