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: allow &5 to allocate and initialize int 5 #19966

Closed
lavalamp opened this issue Apr 13, 2017 · 10 comments
Closed

proposal: spec: allow &5 to allocate and initialize int 5 #19966

lavalamp opened this issue Apr 13, 2017 · 10 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@lavalamp
Copy link

Use case: Many structs intended for json or other serialization use pointers to tell the difference between fields that have been set vs not set. It's currently awkward to declare instances of such structs. An example:

type Settings struct {
  Foo *int
  Bar *string
}

Today one generally does:

func intPtr(i int) *int { return &i }
func strPtr(s string) *string { return &s }

mySettings := Settings{
  Foo: intPtr(5),
  Bar: strPtr("baz"),
}

The proposal would be a language change to just allow:

mySettings := Settings{
  Foo: &5,
  Bar: &"baz",
}

Filing an issue to have a place to discuss (none of my searches turned up a similar feature request).

@ahmetb
Copy link

ahmetb commented Apr 13, 2017

From my personal experience, I use helper functions such as ToIntPtr ToStringPtr to accomplish referencing/unreferencing pointers specifically for JSON etc. serialization use case in the fields: https://godoc.org/github.com/Azure/go-autorest/autorest/to If it goes through a function, you can take address of it and return.

@bradfitz bradfitz changed the title language idea: allow taking address of literals proposal: language idea: allow taking address of literals Apr 13, 2017
@bradfitz bradfitz added v2 A language change or incompatible library change LanguageChange labels Apr 13, 2017
@bradfitz
Copy link
Contributor

Note that all language changes are on hold until any Go2, so this will likely be low priority during future proposal reviews.

@gopherbot gopherbot added this to the Proposal milestone Apr 13, 2017
@griesemer
Copy link
Contributor

If I recall correctly we had actually discussed this possibility back in the early days when we (@rsc in particular) designed the details of addressability. Note that even for composite literals, the use of & as in &T{...} is an exception.

@lavalamp
Copy link
Author

Yeah I definitely wasn't expecting this to get taken up for go 1.9 or even at all.

A common mistake this would prevent is:

i := 5
myStruct := Settings{
  A: &i,
  B: &i,
}

// Then later someone else mutates myStruct.A and B also changes!

I think this issue differs from the old email thread (which I hadn't found, thanks) in that there's an actual use case :)

@rsc rsc changed the title proposal: language idea: allow taking address of literals proposal: spec: allow &5 to allocate and initialize int 5 Jun 16, 2017
@rsc
Copy link
Contributor

rsc commented Jun 16, 2017

See also #9097.

@dsnet
Copy link
Member

dsnet commented Jul 18, 2017

Related to #7054. The pattern for struct fields with *T for builtin types typically descends from the desire to distinguish between the zero-value and an unset value.

@jba
Copy link
Contributor

jba commented Aug 28, 2017

Just an observation: if there were read-only types, then &5 could have type readonly *int, and then it wouldn't require an allocation.

@leighmcculloch
Copy link
Contributor

This is another a pattern I've seen to deal with this inline which isn't great:

myStruct := Settings{
  A: func(i int) *int { return &i }(5),
  B: func(i int) *int { return &i }(5),
}

@bradfitz: I'm lacking some understanding on what causes this to be a language change. Does the language change label indicate it wouldn't be backwards compatible, or that it more generally makes a change to the langauge spec?

@ianlancetaylor
Copy link
Contributor

The LanguageChange label is applied to all proposed changes to the language, whether backward compatible or not.

At this stage we are very unlikely to make any meaningful change to the language before Go 2.

@ianlancetaylor
Copy link
Contributor

Closing as dup of #9097. #9097 is the same idea, but seems slightly more flexible in that it permits specifying the type. (Perhaps this approach is intended to permit the type also, but in any case it seems like a dup.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

10 participants