Matt Joiner
Matt Joiner

Reputation: 118590

Construct a primitive type directly on the heap in Go?

How do I construct a primitive integer type directly on the heap in Go?

For composite literals, the following syntax is supported:

return &File{fd, name, nil, 0}

But no such equivalent seems to exist for int and friends:

Size: &uint64(entry.FileInfo.Size()),

d:\gopath\src\bitbucket.org\anacrolix\dms\dlna\dms\dms.go:271: cannot take the address of uint64(entry.FileInfo.Size())

Upvotes: 3

Views: 1005

Answers (2)

peterSO
peterSO

Reputation: 166704

Address operators

For an operand x of type T, the address operation &x generates a pointer of type *T to x. 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 may also be a composite literal.

Primitive integer types are not addressable. If the integer is a register variable, there is no memory address. If the integer is a constant, providing its memory address would allow it to be modified.

Therefore, create an integer type variable and take its address or use an integer pointer type. For example,

package main

import "fmt"

func main() {
    var i int = 42
    var pi = &i
    j := int(7)
    pj := &j
    var pk = new(int)
    k := *pk
    fmt.Println(i, pi)
    fmt.Println(j, pj)
    fmt.Println(k, pk)
}

Output:

42 0xf840043100
7 0xf840043108
0 0xf840043110

Upvotes: 2

jimt
jimt

Reputation: 26427

Initializing a pointer to a type using new, always allocates it on the heap.

n := new(int64)
*n = entry.FileInfo.Size()
return &n

You can also just take the address of a stack allocated integer. When returning a pointer to a stack allocated object, Go's escape analysis will ensure this object is promoted to the heap. While this does not immediately allocate it on the heap, it will end up there.

n := entry.FileInfo.Size()
return &n

As to your question on why the &T{} approach does not work for primitives, I seem to have forgot. I do know there was a good reason for it, but perhaps someone more knowledgeable can enlighten us on this matter.

Upvotes: 1

Related Questions