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 doesn't print type name for built-in underlying types #24815

Closed
willfaught opened this issue Apr 11, 2018 · 5 comments
Closed

fmt: %#v doesn't print type name for built-in underlying types #24815

willfaught opened this issue Apr 11, 2018 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@willfaught
Copy link
Contributor

What version of Go are you using (go version)?

go version go1.10.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/willfaught/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/willfaught/Developer/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.1/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/_1/ggvd2t1x7hz_185crsb36zlr0000gp/T/go-build166135441=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

https://play.golang.org/p/A22cqb47FB9

What did you expect to see?

(main.Chan)(0x1043a080) (main.Func)(0xd5960) main.Int(1) main.Map{1:1} main.Slice{1} main.Struct{X:1}

Note the main.Int(1) part.

What did you see instead?

(main.Chan)(0x1043a080) (main.Func)(0xd5960) 1 main.Map{1:1} main.Slice{1} main.Struct{X:1}

Note the 1 part.


The type name isn't shown for Int like it is for the composite types like Slice and Map. This can make it difficult to understand the values in a composite type whose nested type(s) is an interface. For example, if the below code prints []Syntax{"a", "b"}, the types of the slice values are ambiguous:

type Syntax interface{ syntax() }

type Comment string
type Identifier string

func (Comment) syntax(){}
func (Identifier) syntax(){}

func main() {
	var s []Syntax = ...
	fmt.Printf("%#v\n", s)
}

This seems to violate the point of the %#v format:

a Go-syntax representation of the value

func main() {
	var s []Syntax = []Syntax{"a", "b"}
	fmt.Printf("%#v\n", s)
}

because the "Go-syntax representation of the value" is invalid:

prog.go:16:28: cannot use "a" (type string) as type Syntax in array or slice literal:
	string does not implement Syntax (missing syntax method)
prog.go:16:33: cannot use "b" (type string) as type Syntax in array or slice literal:
	string does not implement Syntax (missing syntax method)

Maybe this can at least be changed for Go v2?

@ianlancetaylor
Copy link
Contributor

I think there are two different issues here. One is that we don't print a type when printing a numeric or string value with %#v. I think that is working as intended. The other is that when using %#v to print a slice of an interface type, we still don't print the type when printing a numeric value even though the actual type implements the interface. That may be a bug.

CC @robpike

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 11, 2018
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Apr 11, 2018
@willfaught
Copy link
Contributor Author

Thanks for clarifying.

For the second case, I think it should apply outside slices as well. For example, interface{}(Comment("a")) should print as something like main.Comment("a"), whereas Comment("a") can print as just "a".

@dpinela
Copy link
Contributor

dpinela commented Apr 12, 2018

@willfaught But Printf can't distinguish between these two cases, since all of its arguments after the format have static type interface{}. Your second example gets implicitly converted into the first.

@willfaught
Copy link
Contributor Author

Good point.

Maybe it makes sense then to always print the type if it's a named built-in type. Otherwise, the "a" printed by

type T string
fmt.Printf("%#v", T("a"))

isn't syntax for a value with type T.

You can omit it if the type is part of the composite type, like []T{"a"}.

@willfaught
Copy link
Contributor Author

Closing due to no activity.

@willfaught willfaught closed this as not planned Won't fix, can't repro, duplicate, stale Nov 19, 2022
@golang golang locked and limited conversation to collaborators Nov 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants