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 verb does not print nil values for maps or slices #11139

Closed
jhftrifork opened this issue Jun 10, 2015 · 4 comments
Closed

fmt: %v verb does not print nil values for maps or slices #11139

jhftrifork opened this issue Jun 10, 2015 · 4 comments
Milestone

Comments

@jhftrifork
Copy link

Steps to reproduce

package main
import "fmt"
func main() {
    var not_inited map[string]string = nil
    var inited     map[string]string = make(map[string]string)

    fmt.Printf("not_inited = %v\n", not_inited)
    fmt.Printf("inited = %v\n", inited)
}

Expected behavior

$ go run foo.go
not_inited = <nil>
inited = map[]

Actual behavior

$ go run foo.go
not_inited = map[]
inited = map[]

Notes

The nil value inhabits pointer types, function types, interface types, channel types, map types, and slice types. For all of these types, the %v verb should distinguish the nil value from all other values of the type.

Here is a larger program showing the inconsistent behavior of %v:

package main
import "fmt"
func main() {
    var pointer_not_inited    *string            = nil
    var pointer_inited        *string            = (func(s string) *string { return &s; })("foo")

    var func_not_inited       func(string)string = nil
    var func_inited           func(string)string = func(s string) string { return s; }

    var interface_not_inited  interface{}        = nil
    var interface_inited      interface{}        = "foo"

    var channel_not_inited    chan string        = nil
    var channel_inited        chan string        = make(chan string)

    var map_not_inited        map[string]string  = nil
    var map_inited            map[string]string  = make(map[string]string)

    var slice_not_inited      []string           = nil
    var slice_inited          []string           = make([]string, 0)

    fmt.Printf("pointer_not_inited = %v\n", pointer_not_inited)
    fmt.Printf("pointer_inited = %v\n", pointer_inited)

    fmt.Printf("func_not_inited = %v\n", func_not_inited)
    fmt.Printf("func_inited = %v\n", func_inited)

    fmt.Printf("interface_not_inited = %v\n", interface_not_inited)
    fmt.Printf("interface_inited = %v\n", interface_inited)

    fmt.Printf("channel_not_inited = %v\n", channel_not_inited)
    fmt.Printf("channel_inited = %v\n", channel_inited)

    fmt.Printf("slice_not_inited = %v\n", slice_not_inited)
    fmt.Printf("slice_inited = %v\n", slice_inited)

    fmt.Printf("map_not_inited = %v\n", map_not_inited)
    fmt.Printf("map_inited = %v\n", map_inited)
}
@cznic
Copy link
Contributor

cznic commented Jun 10, 2015

@jhftrifork
Copy link
Author

I just looked; the %#v verb is better. I'll stop using %v from now on then.

The issue I mentioned is serious: it cost me a lot of time debugging due to my (sensible) assumption that a value was not nil when in fact it was. If %v cannot be changed, I would suggest that the documentation mark %v as deprecated and encourage the use of %#v.

@ianlancetaylor ianlancetaylor added this to the Go1.6 milestone Jun 10, 2015
@ianlancetaylor
Copy link
Member

I'm not sure whether we can make this change or not. Sending to Rob to decide.

@mikioh mikioh changed the title fmt %v verb does not print nil values for maps or slices fmt: %v verb does not print nil values for maps or slices Jun 11, 2015
@robpike
Copy link
Contributor

robpike commented Aug 26, 2015

Working as intended, with an easy workaround (%#v). Shouldn't change behavior like this.

@robpike robpike closed this as completed Aug 26, 2015
@golang golang locked and limited conversation to collaborators Sep 4, 2016
@rsc rsc unassigned robpike Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants