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: reflect.Value.IsZero #7501

Closed
lukescott opened this issue Mar 10, 2014 · 17 comments
Closed

reflect: reflect.Value.IsZero #7501

lukescott opened this issue Mar 10, 2014 · 17 comments
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done. Proposal Proposal-Accepted
Milestone

Comments

@lukescott
Copy link

Many encoding packages have a custom internal "isEmptyValue" function. The
functionality is pretty much identical. This expands to other packages that use reflect,
such as an ORM (is primary key set?).

It would be useful to have a standard "IsZero" method on reflect.Value,
something like this (copied from encoding/xml):

func (v Value) IsZero() bool {
    switch v.Kind() {
    case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
        return v.Len() == 0
    case reflect.Bool:
        return !v.Bool()
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
        return v.Int() == 0
    case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
        return v.Uint() == 0
    case reflect.Float32, reflect.Float64:
        return v.Float() == 0
    case reflect.Interface, reflect.Ptr:
        return v.IsNil()
    }
    return false
}
@bradfitz
Copy link
Contributor

Comment 1:

At least for Map and Slice, though, there's a difference between nil and Len 0.

@robpike
Copy link
Contributor

robpike commented Mar 26, 2014

Comment 2:

I believe this is correct:
func (v Value) IsZero() bool {
    switch v.Kind() {
    case reflect.Array, reflect.String:
        return v.Len() == 0
    case reflect.Bool:
        return !v.Bool()
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
        return v.Int() == 0
    case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
        return v.Uint() == 0
    case reflect.Float32, reflect.Float64:
        return v.Float() == 0
    case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
        return v.IsNil()
    }
    return false
}
it seems a reasonable feature request.

Labels changed: added release-go1.4, repo-main.

Status changed to Accepted.

@extemporalgenome
Copy link
Contributor

Comment 3:

r's suggested revision still slightly deviates from the language defined notion of a
type's zero value. Arrays and structs are zero if all their members have respective zero
values. Yes, zero-size types (such as with the above array length check) are guaranteed
to be their own zero value, but that's not a particularly common scenario.
Zero length slices and maps would only be zero if they're also nil.

@rsc
Copy link
Contributor

rsc commented Sep 16, 2014

Comment 4:

We could define IsZero but it won't be usable in any of the packages that define their
own 'emptiness' predicates.

@lukescott
Copy link
Author

Comment 5:

Perhaps there could be an "IsZero" and "IsEmpty" method. "IsEmpty" would be the same as
"IsZero", but also include zero length slices and maps.
Including structs would be nice, although the current omitempty implementations in
encoding/* don't. However, that doesn't mean those implementations have to use "IsEmpty"
for Go 1. Third party / internal encoding libraries may choose to use the method though,
which still makes it useful to implement.

@rsc
Copy link
Contributor

rsc commented Sep 29, 2014

Comment 6:

Maybe for 1.5.

Labels changed: added release-go1.5, removed release-go1.4.

@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014
@rsc rsc removed accepted labels Apr 14, 2015
@bradfitz bradfitz modified the milestones: Go1.6, Go1.5 Jul 7, 2015
@rsc
Copy link
Contributor

rsc commented Oct 16, 2015

It's not clear to me what would use IsZero if we added it.
It's easy for packages to define what they really want themselves.
I'm wary of continuing to add to reflect.
I don't want it to be a kitchen sink of helpers.

@hraban
Copy link

hraban commented Oct 26, 2015

Not arguing for or against, just a datapoint on intuitiveness: I found this page while looking for a reflect.IsZero that would actually test for zero values of structs.

reflect.IsZero(x) feels like it should return true for any y in var x y, to me.

But this is moot if it's not added.

@rsc rsc modified the milestones: Go1.6Maybe, Go1.6, Go1.7 Nov 25, 2015
@rsc
Copy link
Contributor

rsc commented Nov 25, 2015

Postponing to Go 1.7 (Go1.6Maybe was a misclick), along with discussion of omitzero in xml and json.

@gopherbot
Copy link

CL https://golang.org/cl/23064 mentions this issue.

@bradfitz bradfitz modified the milestones: Go1.8, Go1.7 May 12, 2016
@quentinmit quentinmit added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Oct 10, 2016
@rsc rsc added this to the Go1.9Early milestone Oct 18, 2016
@equt
Copy link

equt commented Feb 24, 2019

Any updates on this topic? This should be a reasonable feature request.

@ianlancetaylor
Copy link
Contributor

I'll turn this into a proposal for consideration.

@ianlancetaylor ianlancetaylor changed the title reflect: feature request: IsZero method proposal: reflect: reflect.Value.IsZero Feb 25, 2019
@ianlancetaylor ianlancetaylor added Proposal and removed NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. early-in-cycle A change that should be done early in the 3 month dev cycle. FeatureRequest labels Feb 25, 2019
@ianlancetaylor ianlancetaylor modified the milestones: Unplanned, Proposal Feb 25, 2019
@josharian
Copy link
Contributor

Note that there’s also discussion of an internal runtime.isZero for optimized codegen:
#23929

@andybons
Copy link
Member

Proposal tentatively approved. @rsc any objections?

@andybons andybons changed the title proposal: reflect: reflect.Value.IsZero reflect: reflect.Value.IsZero Mar 27, 2019
@ianlancetaylor ianlancetaylor added help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Mar 27, 2019
@ianlancetaylor ianlancetaylor modified the milestones: Proposal, Unplanned Mar 27, 2019
@gopherbot
Copy link

Change https://golang.org/cl/171337 mentions this issue: reflect: implement Value.IsZero()

@go101
Copy link

go101 commented Apr 13, 2019

So, this will be available in Go 1.13?

@andybons
Copy link
Member

@go101 yes.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done. Proposal Proposal-Accepted
Projects
None yet
Development

No branches or pull requests