Is there +v Stringer interface?

121 views
Skip to first unread message

yves baumes

unread,
Jun 24, 2020, 4:34:23 PM6/24/20
to golang-nuts
When I want to override the '%v' format, I declare a String() method.
When I want to override the '%#v' format, I declare a GoString() method.

But there is nothing about '%+v'? There is no PlusStringer() method ?

Let's take the following exemple, the %v and %+v formatter prints the exact same results. Which is annoying somehow..  

```
package main

import ("fmt")

type page struct {
title string
body  []byte
}

func (p *page) String() string {
return fmt.Sprint("{ ", p.title, " ", string(p.body), " }")
}

func main() {
const title = "helloworld"
const text = "Hello everyone"
p := &page{title: title, body: []byte(text)}
log.Printf("p = %v", p) // prints p = { helloworld Hello everyone }
log.Printf("p = %+v", p) // prints p = { helloworld Hello everyone }
log.Printf("p = %#v", p) // prints p = &main.page{title:"helloworld", body:[]uint8{0x48, 0x65, 0x6c, [etc]
}

```

Any clue on how to adapt the String() method to print the fields names?



Ian Cottrell

unread,
Jun 24, 2020, 5:33:12 PM6/24/20
to yves baumes, golang-nuts
You want to implement fmt.Formatter.
In general I prefer implementing Formatter to either Stringer or GoStringer if I am only doing it for printing, even for the simple cases, as I feel it better reflects the intent.
I reserve implementing the String method for when I really do want to be able to access the value programmatically as a string and it is possible to do so in a way that is more efficient than printing it.

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/2506ab0c-5558-4c72-8ad4-a8ad0006ea08o%40googlegroups.com.

Ian Davis

unread,
Jun 24, 2020, 7:41:01 PM6/24/20
to golan...@googlegroups.com
fmt.Formatter is woefully under documented. The second argument (called c in the interface definition) is the verb, i.e. 's', 'v', 'd' etc. The first argument provides a state interface with functions to allow you to emit the format of your type. The Flag function on this interface lets you test the type of format requested. Despite this being an int (also confusingly called c) it's actually a character, i.e. '#', '+', ' ' etc.

So if someone writes fmt.Sprintf("%+v", yourtype) you will be passed 'v' as the verb and you must call Flag('+') to test if the caller wants the '+' form.

Miki Tebeka

unread,
Jun 24, 2020, 11:57:33 PM6/24/20
to golang-nuts

On Thursday, June 25, 2020 at 2:41:01 AM UTC+3, Ian Davis wrote:
fmt.Formatter is woefully under documented.

andrey mirtchovski

unread,
Jun 25, 2020, 12:37:58 AM6/25/20
to golang-nuts
>> fmt.Formatter is woefully under documented.
>
> My reference is pkg/errros - https://github.com/pkg/errors/blob/master/errors.go#L127

we have wasted tens of man-hours hunting for a bug that didn't
manifest in logs due to that custom formatter. %#v basically went
directly to stringer without embedding type information (the
fallthrough, line 135 in the link you linked). it was difficult to
hunt and lead us to believe that custom formatters should be avoided.
in the end we switched away from pkg/errors using the new stuff
available as standard in go 1.14. the other lesson we learned is that
it's better to be explicit than implicit. wrapping nil errors with
.Wrap returning nil resulted in a lot of assumptions that confused
coders not experienced with that package. when we switched to %w
errors popped up where not expected because the explicitness of the %w
flag doesn't allow a nil error to be used with it.

nothing against the package, it served us well for a very long time.
but it was time for a change.

yves baumes

unread,
Jun 25, 2020, 3:22:57 AM6/25/20
to golang-nuts
Thank you all :) 

--
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.
Reply all
Reply to author
Forward
0 new messages