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

reflect: Value.Elem() inconsistency betwen go1.4.3 and go.15 #12954

Closed
odeke-em opened this issue Oct 16, 2015 · 4 comments
Closed

reflect: Value.Elem() inconsistency betwen go1.4.3 and go.15 #12954

odeke-em opened this issue Oct 16, 2015 · 4 comments

Comments

@odeke-em
Copy link
Member

In some code whose struct

type pushCmd struct {
    Hidden         *bool   `json:"hidden"`
    Source         *string `json:"source"`
    Convert        *bool   `json:"convert"`
    Ocr            *bool   `json:"ocr"`
    IgnoreChecksum *bool   `json:"ignore-checksum"`
}

I perform some value extraction by json tag and fill in a fresh pushCmd value with a mix of already defined values from a resource configuration and those already entered in the from value. However, running the exact same program http://play.golang.org/p/4NRzI-ejuc on go1.4.3 and then on go.1.5 gives different results
golang-inconsistency
The code example and results are at https://github.com/odeke-em/bugs/tree/master/golang/reflect-inconsistency

@nodirt
Copy link
Contributor

nodirt commented Oct 16, 2015

Distilled, fmt.Println(reflect.ValueOf(true)) changed. In Go 1.4 this prints <bool Value>. In Go 1.5, this prints true.

This doesn't violate Go 1 compatibility guidelines, which says The Go specification tries to be explicit about most properties of the language, but there are some aspects that are undefined. Programs that depend on such unspecified behavior may break in future releases.

In Go 1.4.3 fmt didn't specify how it formats reflect.Value. It have been specified only in Go 1.5

Note that reflect.ValueOf(true).String() value didn't change.

@nodirt
Copy link
Contributor

nodirt commented Oct 16, 2015

Actually, I admit it was a breaking change because fmt specification essentially changed: the rule

If an operand implements method String() string, that method
will be invoked to convert the object to a string, which will then
be formatted as required by the verb (if any).

applied to reflect.Value in the past. I still don't think anything will be done about this.

@ianlancetaylor
Copy link
Contributor

The change is documented in https://golang.org/go1.5.html. I don't consider it to be a Go 1 compatibility breaking change: if we changed reflect.Value.String that wouldn't be a breaking change either. Breaking user types would be a breaking change. The handling of library defined types is up to the library.

odeke-em pushed a commit to odeke-em/drive that referenced this issue Oct 21, 2015
Use elem.Interface() to get the value instead of
implicitly relying on fmt.*Printf("%v", elem)
due to a discrepenacy between Go1.5  and < Go1.5
ie golang/go#12954
@odeke-em
Copy link
Member Author

Alright, thank you folks for taking a look at this. My way around it was to invoke ".Interface()"

-   fmt.Sprintf("%v", elem)
+   fmt.Sprintf("%v", elem.Interface())

and that produces the desired result between go 1.5 and 1.4.3.

@golang golang locked and limited conversation to collaborators Oct 24, 2016
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

4 participants