Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 228162
Next
Alex Hales
  • 0
Alex HalesTeacher
Asked: July 31, 20222022-07-31T07:03:06+00:00 2022-07-31T07:03:06+00:00In: Go, literals, pointers, struct

pointers – How do I do a literal *int64 in Go?

  • 0

[ad_1]

The Go Language Specification (Address operators) does not allow to take the address of a numeric constant (not of an untyped nor of a typed constant).

The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

For reasoning why this isn’t allowed, see related question: Find address of constant in go. A similar question (similarly not allowed to take its address): How can I store reference to the result of an operation in Go?

0) Generic solution (from Go 1.18)

Generics are added in Go 1.18. This means we can create a single, generic Ptr() function that returns a pointer to whatever value we pass to it. Hopefully it’ll get added to the standard library. Until then, you can use github.com/icza/gog, the gog.Ptr() function (disclosure: I’m the author).

This is how it can look like:

func Ptr[T any](v T) *T {
    return &v
}

Testing it:

i := Ptr(2)
log.Printf("%T %v", i, *i)

s := Ptr("abc")
log.Printf("%T %v", s, *s)

x := Ptr[any](nil)
log.Printf("%T %v", x, *x)

Which will output (try it on the Go Playground):

2009/11/10 23:00:00 *int 2
2009/11/10 23:00:00 *string abc
2009/11/10 23:00:00 *interface {} <nil>

Your other options (prior to Go 1.18) (try all on the Go Playground):

1) With new()

You can simply use the builtin new() function to allocate a new zero-valued int64 and get its address:

instance := SomeType{
    SomeField: new(int64),
}

But note that this can only be used to allocate and obtain a pointer to the zero value of any type.

2) With helper variable

Simplest and recommended for non-zero elements is to use a helper variable whose address can be taken:

helper := int64(2)
instance2 := SomeType{
    SomeField: &helper,
}

3) With helper function

Note: Helper functions to acquire a pointer to a non-zero value are available in my github.com/icza/gox library, in the gox package, so you don’t have to add these to all your projects where you need it.

Or if you need this many times, you can create a helper function which allocates and returns an *int64:

func create(x int64) *int64 {
    return &x
}

And using it:

instance3 := SomeType{
    SomeField: create(3),
}

Note that we actually didn’t allocate anything, the Go compiler did that when we returned the address of the function argument. The Go compiler performs escape analysis, and allocates local variables on the heap (instead of the stack) if they may escape the function. For details, see Is returning a slice of a local array in a Go function safe?

4) With a one-liner anonymous function

instance4 := SomeType{
    SomeField: func() *int64 { i := int64(4); return &i }(),
}

Or as a (shorter) alternative:

instance4 := SomeType{
    SomeField: func(i int64) *int64 { return &i }(4),
}

5) With slice literal, indexing and taking address

If you would want *SomeField to be other than 0, then you need something addressable.

You can still do that, but that’s ugly:

instance5 := SomeType{
    SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5

What happens here is an []int64 slice is created with a literal, having one element (5). And it is indexed (0th element) and the address of the 0th element is taken. In the background an array of [1]int64 will also be allocated and used as the backing array for the slice. So there is a lot of boilerplate here.

6) With a helper struct literal

Let’s examine the exception to the addressability requirements:

As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

This means that taking the address of a composite literal, e.g. a struct literal is ok. If we do so, we will have the struct value allocated and a pointer obtained to it. But if so, another requirement will become available to us: “field selector of an addressable struct operand”. So if the struct literal contains a field of type int64, we can also take the address of that field!

Let’s see this option in action. We will use this wrapper struct type:

type intwrapper struct {
    x int64
}

And now we can do:

instance6 := SomeType{
    SomeField: &(&intwrapper{6}).x,
}

Note that this

&(&intwrapper{6}).x

means the following:

& ( (&intwrapper{6}).x )

But we can omit the “outer” parenthesis as the address operator & is applied to the result of the selector expression.

Also note that in the background the following will happen (this is also a valid syntax):

&(*(&intwrapper{6})).x

7) With helper anonymous struct literal

The principle is the same as with case #6, but we can also use an anonymous struct literal, so no helper/wrapper struct type definition needed:

instance7 := SomeType{
    SomeField: &(&struct{ x int64 }{7}).x,
}

[ad_2]

  • 0 0 Answers
  • 10 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 4778 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 1063 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 1009 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.