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

Comments

Projects
None yet
5 participants
@jhftrifork
Copy link

jhftrifork commented Jun 10, 2015

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

This comment has been minimized.

Copy link
Contributor

cznic commented Jun 10, 2015

@jhftrifork

This comment has been minimized.

Copy link
Author

jhftrifork commented Jun 10, 2015

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

This comment has been minimized.

Copy link
Contributor

ianlancetaylor commented Jun 10, 2015

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

This comment has been minimized.

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 Aug 26, 2015

@golang golang locked and limited conversation to collaborators Sep 4, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.