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: Address operator for basic and bool literals #39085

Closed
vladimirvivien opened this issue May 15, 2020 · 2 comments
Closed

proposal: Address operator for basic and bool literals #39085

vladimirvivien opened this issue May 15, 2020 · 2 comments

Comments

@vladimirvivien
Copy link

@vladimirvivien vladimirvivien commented May 15, 2020

Currently in Go, the address operator (&) can only be applied to an addressable element (i.e. a variable, pointer indirection, slice indexing, addressable struct fields, and composite literals). However, if you are using numeric, string, or bool literals, the address operator is not supported. This usually forces some awkward workarounds that either use intermediate variables, or boxed values (basic literals wrapped in composite types), or helper functions that return pointers for their passed values.

Proposal

As mentioned earlier, the address operator can be applied to composite literals to automatically return the address of their respective values as illustrated below:

type myT struct{a string}
a := &myT{"A"}
x := &struct{a string; b int}{"A", 12}
y := &[]string{"A","B"}
z := &[1]int{2}

This proposal calls for extending this mechanism so that the address operator could also support numeric, string, and boolean literal operands. To minimize impact on the language, the proposal calls for the reuse of the same lexical format used for composite literals, mainly:

"&" basic_types | bool "{" BasicLit | BoolConstant"}"

The following shows examples of how the address operator would be applied to basic and boolean literal values to automatically return their respective addresses:

t := struct {
    f1 *int
    f2 *string
    f3 *float64
    f4 [2]*int64
    f5 *bool
}{
    f1: &int{12},
    f2: &string{"Hi!"},
    f3: &float64{3.14},
    f4: [2]*int64{&int64{44}, &int64{12}},
    f5: &bool{true},
}

By contrast, one of the ways to do the same thing today requires an intermediate set of variable assignments as shown below:

f1 := 12
f2 := "Hi!"
f3 := float64(3.14)
var a, b int64 = 44, 12
f5 := false

t := struct {
    f1 *int
    f2 *string
    f3 *float64
    f4 [2]*int64
    f5 *bool
}{
    f1: &f1,
    f2: &f2,
    f3: &f3,
    f4: [2]*int64{&a, &b},
    f5: &f5,
}

Another workaround uses a sort of type boxing that declares additional types that can wrap basic values inside corresponding struct values:

type Int struct{Value int}
type String struct {Value string}
type Float64 struct{Value float64}
type Int64 struct{Value int64}
type Bool struct{Value bool}
...
t := struct {
    f1 *Int
    f2 *String
    f3 *Float64
    f4 [2]*Int64
    f5 *Bool
}{
    f1: &Int{12},
    f2: &String{"Hi!"},
    f3: &Float64{3.14},
    f4: [2]*Int64{&Int64{44}, &Int64{12}},
    f5: &Bool{true},
}

Some codebase uses yet another workaround that define a set of additional helper functions to provide the convenience of returning the addresses of their passed values as shown:

func Int(v int) *int {return &v}
func String (v string) *string {return &v}
func Float64(v float64) *float64 {return &v}
func Int64(v int64) *int64 {return &v}
func Bool(v bool) *bool {return &v}

t := struct {
    f1 *int
    f2 *string
    f3 *float64
    f4 [2]*int64
    f5 *bool
}{
    f1: Int(12),
    f2: String("Hi!"),
    f3: Float64(3.14),
    f4: [2]*int64{Int64(44), Int64(12)},
    f5: &Bool(true),
}
@gopherbot gopherbot added this to the Proposal milestone May 15, 2020
@gopherbot gopherbot added the Proposal label May 15, 2020
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 15, 2020

Dup of #9097?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 19, 2020

Closing as dup of #9097.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.