-
Notifications
You must be signed in to change notification settings - Fork 18k
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: GoStringer checks should test non-pointer types for pointer-based GoStringer receiver #21230
Comments
The method set of T does not include methods defined on *T. Working as intended. |
fmt's It's counter-intuitive because if one invokes Stringer example: https://play.golang.org/p/FRGf4klCBB |
I do not think this request can be seen in isolation to the fmt package but the argument would apply to many other interfaces in the same way. Only changing how fmt works would also be inconsistent with other interface checks in the std lib. That said the language spec https://golang.org/ref/spec#Method_sets notes.
I do not see this (if possible at all) being added the other way around to solve this on a language level for go1 as that looks like a major language change that is not backwards compatible to me. |
Using T as a receiver is one possible solution, but it forces pass by value semantics, which may have other consequences. For example, this approach is not compatible with a I wouldn't want inconsistencies in the std lib. But I do want a language and std lib that are intuitive and mostly gotcha-free. The suggestion to use T as a receiver could work for the playground toys I've included here. But it doesn't seem like a solution that would scale to a more complex code base. |
There's nothing to do here. If the GoString method is defined on a pointer receiver, then for fmt.Printf to use it, you have to pass a pointer to the instance. That's the only option. |
I can not see how we can obtain a more consistent behavior with the suggestion. Additionally i think we cant even obtain the pointer arbitrary values to call Stringer on them as the reflect package which fmt uses does not seem to support that. The suggestion would also be a backwards incompatible change which does not seem to warrant the breakage it might cause. For the struct with mutex used by Stringer to work we can either pass the pointer to T to fmt or the mutex could be referenced by a pointer within the struct. |
I don't think there is anything we can do here. Please comment if you disagree. |
What version of Go are you using (
go version
)?go1.8.1
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/vagrant/mesos-go-workspace"
GORACE=""
GOROOT="/usr/local/go-1.8.1"
GOTOOLDIR="/usr/local/go-1.8.1/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build763882381=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
What did you do?
https://play.golang.org/p/YL3Dz_tXtF
What did you expect to see?
The GoStringer implementation invoked for all cases.
What did you see instead?
The GoStringer implementation was only invoked for pointer types.
The text was updated successfully, but these errors were encountered: