Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fmt: %+#v or %#+v: underspecified? #44278

Closed
musiphil opened this issue Feb 15, 2021 · 6 comments
Closed

fmt: %+#v or %#+v: underspecified? #44278

musiphil opened this issue Feb 15, 2021 · 6 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@musiphil
Copy link

I saw someone trying to use %+#v or %#+v with fmt, but I couldn't find in the doc what it's supposed to do (or even whether it's valid).

I think this is the only relevant clause:

%v	the value in a default format
	when printing structs, the plus flag (%+v) adds field names
%#v	a Go-syntax representation of the value

which doesn't seem to say unambiguously which one should take precedence when both # and + are used. There's some asymmetry in the description of %+v and %#v, which seems to suggest that # takes precedence, but it's far from clear.

I believe the descriptions for both should fall under that of %v, with an added disambiguation for +# or #+.

  1. If the %v verb is used with the # flag (%#v) and the operand implements the GoStringer interface, that will be invoked.

This seems to favor # whenever it's used, but it doesn't apply unless the operand implements the GoStringer interface.

@ianlancetaylor
Copy link
Contributor

I don't see any ambiguity here. Both + and # are formatting flags and both can be specified. The documentation lists a series of steps "in order of application," so as it says if the value implements the GoString method then the + flag is ignored. Other than that as far as I can see %#v and %#+v only differ if the value implements the Formatter interface, and the Format method pays attention to both Flag('#') and Flag('+').

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Feb 16, 2021
@musiphil
Copy link
Author

The question is what happens when the operand implements neither the Formatter or the GoStringer interface; e.g. for an operand of a []string type, can we read from the documentation whether it is supposed to give [hello world] or []string{"hello", "world"}?

@ianlancetaylor
Copy link
Contributor

I don't see anything that says that the + flag should have any effect on printing a slice. So for a slice with none of the magic methods I would expect that %#v and %+#v would be the same. And that is what I see in practice.

@musiphil
Copy link
Author

Sorry, I messed up the example at the last minute by trying to substitute a "simpler" one.
Please take a struct with a field of type string for example:

type Link struct { A, Z string }
l := Link{A: "n1:2", Z: "n2:1"}
fmt.Printf("%v\n", l)	// {n1:2 n2:1}
fmt.Printf("%+v\n", l)	// {A:n1:2 Z:n2:1}
fmt.Printf("%#v\n", l)	// pkg.Link{A:"n1:2", Z:"n2:1"}

How do we interpret the documentation to figure out what we get with %#+v?

We could take that the output of %#v should also be fine for that of %#+v for it "adds field names" as well, but I feel it could be rather coincidental than intended. And I was thinking it would be much more straightforward to explicitly mention that + is redundant for struct when # is specified.

@ianlancetaylor
Copy link
Contributor

%#v for a struct is expected to add field names, since those field names will appear in the "Go-syntax representation of the value.". So it does seem to me that %#v and %#+v should be expected to generate identical output. I don't see how else the read the current docs.

Given that I don't think the docs can be read another way, and given that %#+v is bound to be unusual, I'm not sure it's really helpful to explicitly document its behavior. But I'm open to counter-argument if you can show how the current docs are ambiguous. You said the current docs could be "rather coincidental than intended," and I agree, but I don't think they are ambiguous.

@mvdan
Copy link
Member

mvdan commented Jun 15, 2021

Closing old issues that still have the WaitingForInfo label where enough details to investigate weren't provided. Feel free to leave a comment with more details and we can reopen.

@mvdan mvdan closed this as completed Jun 15, 2021
@golang golang locked and limited conversation to collaborators Jun 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants