Go: proposal: spec: allow &5 to allocate and initialize int 5

Created on 13 Apr 2017  路  10Comments  路  Source: golang/go

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).

FrozenDueToAge Go2 LanguageChange Proposal

Most helpful comment

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.

All 10 comments

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.

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

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.

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 :)

See also #9097.

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.

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

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?

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.

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.)

Was this page helpful?
0 / 5 - 0 ratings