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

proposal: spec: direct reference to embedded fields in struct literals #9859

Open
adg opened this issue Feb 12, 2015 · 10 comments

Comments

@adg
Copy link
Contributor

commented Feb 12, 2015

Consider

type E struct {
    A int
}

type T struct {
    E
}

This works:

T{E: E{A: 1}}

This does not:

T{A: 1}

Makes some struct literals more verbose than they need be, and makes them asymmetrical to their usage (where you can access the embedded struct's fields directly).

Can we allow it?

(cc @bradfitz)

@adg

This comment has been minimized.

Copy link
Contributor Author

commented Feb 12, 2015

One possible argument against is that it allows you to effectively specify the same field twice, for example:

T{E: E{A: 1}, A: 2}

But this case already exists

S{B: 2, B: 3}

and is disallowed, so maybe that isn't worth worrying about.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Feb 12, 2015

FWIW, @adg and I both tripped over this independently. We both assumed T{A: 1} would work.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Feb 12, 2015

I've wished to be to able to do this many times (go/ast is a prime example).

I don't know that we ever thought through all the consequences, but it's perhaps worthwhile considering.

@griesemer griesemer self-assigned this Feb 12, 2015

@dominikh

This comment has been minimized.

Copy link
Member

commented Feb 13, 2015

Is there any known reason it wasn't considered back in #164?

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2015

@dominikh issue #164 was about a "programmer error" or misunderstanding of the spec as written.

Usually we don't look at each such error and consider a spec change. However this has come up before (it has restricted what I wanted to do in APIs significantly) so maybe it's time to at least investigate the consequences of such a language change more thoroughly.

That said, language changes are really very low priority. We'll get to it when we get to it.

@josharian

This comment has been minimized.

Copy link
Contributor

commented Feb 18, 2015

r's comment on this on golang-nuts was:

It might one day, but as it stands the requirement to provide more information is more robust against changes in the data types.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc removed the priority-low label Apr 10, 2015

rsc added a commit that referenced this issue Jun 22, 2015
net/url: add RawPath field, a hint at the desired encoding of Path
Historically we have declined to try to provide real support for URLs
that contain %2F in the path, but they seem to be popping up more
often, especially in (arguably ill-considered) REST APIs that shoehorn
entire paths into individual path elements.

The obvious thing to do is to introduce a URL.RawPath field that
records the original encoding of Path and then consult it during
URL.String and URL.RequestURI. The problem with the obvious thing
is that it breaks backward compatibility: if someone parses a URL
into u, modifies u.Path, and calls u.String, they expect the result
to use the modified u.Path and not the original raw encoding.

Split the difference by treating u.RawPath as a hint: the observation
is that there are many valid encodings of u.Path. If u.RawPath is one
of them, use it. Otherwise compute the encoding of u.Path as before.

If a client does not use RawPath, the only change will be that String
selects a different valid encoding sometimes (the original passed
to Parse).

This ensures that, for example, HTTP requests use the exact
encoding passed to http.Get (or http.NewRequest, etc).

Also add new URL.EscapedPath method for access to the actual
escaped path. Clients should use EscapedPath instead of
reading RawPath directly.

All the old workarounds remain valid.

Fixes #5777.
Might help #9859.
Fixes #7356.
Fixes #8767.
Fixes #8292.
Fixes #8450.
Fixes #4860.
Fixes #10887.
Fixes #3659.
Fixes #8248.
Fixes #6658.
Reduces need for #2782.

Change-Id: I77b88f14631883a7d74b72d1cf19b0073d4f5473
Reviewed-on: https://go-review.googlesource.com/11302
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>

@rsc rsc changed the title spec: direct reference to embedded fields in struct literals proposal: spec: direct reference to embedded fields in struct literals Jun 20, 2017

@rsc rsc added the Go2 label Jun 20, 2017

@ghasemloo

This comment has been minimized.

Copy link

commented Jul 11, 2017

I have also written code that assumed this would work.

Considering the reading and assignment of embedded fields work it is quite unintuitive that this doesn't.

https://goplay.googleplex.com/p/d9tdQxQism

@dsnet dsnet added the Proposal label Aug 7, 2017

@dsnet dsnet modified the milestones: Proposal, Unplanned Aug 7, 2017

@zombiezen

This comment has been minimized.

Copy link
Contributor

commented Aug 17, 2017

@neild and I were discussing this and there are two things that would have to be addressed (not showstoppers, just considerations to make):

  1. What happens if both the anonymous field containing the embedded field and the embedded field itself are specified?
T{E: E{}, A: 42}

This is probably a compile error, much like specifying duplicate fields in struct literals today.

  1. What happens if the anonymous field is a pointer type? Should setting an embedded field cause the anonymous field to be implicitly allocated?

I also suspect that this could be done before Go 2, since it makes previously invalid Go programs valid, and shouldn't alter the meaning of existing Go programs.

@ghasemloo

This comment has been minimized.

Copy link

commented Aug 27, 2017

How much should we be consistent with assignments? If 1 is a compile error should the following also be a compile error?
https://goplay.googleplex.com/p/9CL_5Owvzi

For 2, in assignments you would get a runtime error. I feel the idea of allocation on the fly can obscure memory allocation and if you have multiple nested embedding a simple int assignment would do a lot more than a user would expect and surprise them. So I feel it might be better to just have a runtime error as in the case of assignment and no hidden memory allocation:
https://goplay.googleplex.com/p/HWSFemHcFf
Also that is the behavior without embedding:
https://goplay.googleplex.com/p/ixVAW3xa-Q

@neild

This comment has been minimized.

Copy link
Contributor

commented Aug 28, 2017

The assignment rules already cover the case where the same value (or part of a value) appears multiple times in an assignment.

The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

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