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: clarify behavior for unexported names #4876

Closed
adonovan opened this issue Feb 22, 2013 · 6 comments
Closed

reflect: clarify behavior for unexported names #4876

adonovan opened this issue Feb 22, 2013 · 6 comments

Comments

@adonovan
Copy link
Member

Exported field names inhabit a global namespace but unexported (lower case) field names
belong to the namespace of the package in which they lexically appear.

The "reflect" API doesn't mention this, which can lead to surprising results
when searching for a lowercase field by name.

   func (v Value) FieldByName(name string) Value
   FieldByName returns the struct field with the given name.
   It returns the zero Value if no field was found.
   It panics if v's Kind is not struct.

In the example below, a struct has two fields, both called r, but belonging to different
namespaces.  The "reflect" algorithm, when searching for "r", finds
both, and assumes there's a conflict when in reality there isn't.  Without changing the
existing API, that's the best we can do, but it would be useful to document this because
otherwise the choice of unexported field names inside one package can have subtle
effects on another package using reflection.

http://play.golang.org/p/WTj5d06CQ3

(gri: I know you know all this already.)
@adonovan
Copy link
Member Author

Comment 1:

(gri -> rsc)

Owner changed to @rsc.

@rsc
Copy link
Contributor

rsc commented Feb 22, 2013

Comment 2:

It's tempting to just remove support for lower case names from FieldByName.
The current behavior is arguably incorrect.

@adonovan
Copy link
Member Author

Comment 3:

Perhaps the most correct solution is to add another method:
 // Precondition: !ast.IsExported(fieldname) <=> pkgpath != ""
 FieldFieldByQualifiedName(pkgpath, fieldname string)
which also compares the StructField.PkgPath, not just the name.
The first method could be changed in one of the following ways:
(a) document its tricky behaviour but remain unchanged.
(b) reject lowercase field names.
(b) accept lowercase field names, and in that case reflect over the callstack (!) and
extract the default package name from the calling frame, and then pass that to the
qualified 2-arg function.

@rsc
Copy link
Contributor

rsc commented Mar 12, 2013

Comment 4:

Leaving for Go 1.2. Not important enough.

Labels changed: added priority-later, go1.2, removed priority-triage, go1.1maybe.

@rsc
Copy link
Contributor

rsc commented Sep 10, 2013

Comment 5:

Labels changed: added documentation.

@rsc
Copy link
Contributor

rsc commented Sep 13, 2013

Comment 6:

This issue was closed by revision 7fb3d8e.

Status changed to Fixed.

@rsc rsc added this to the Go1.2 milestone Apr 14, 2015
@rsc rsc removed the go1.2 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
@rsc rsc removed their assignment Jun 22, 2022
This issue was closed.
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

3 participants