Address of a temporary in Go?

后端 未结 8 743
不知归路
不知归路 2021-02-01 13:24

What\'s the cleanest way to handle a case such as this:

func a() string {
    /* doesn\'t matter */
}

b *string = &a()

This generates the

相关标签:
8条回答
  • 2021-02-01 14:11

    You can't get the reference of the result directly when assigning to a new variable, but you have idiomatic way to do this without the use of a temporary variable (it's useless) by simply pre-declaring your "b" pointer - this is the real step you missed:

    func a() string {
        return "doesn't matter"
    }
    
    b := new(string) // b is a pointer to a blank string (the "zeroed" value)
    *b = a()         // b is now a pointer to the result of `a()`
    

    *b is used to dereference the pointer and directly access the memory area which hold your data (on the heap, of course).

    Play with the code: https://play.golang.org/p/VDhycPwRjK9

    0 讨论(0)
  • 2021-02-01 14:14

    I recently was tied up in knots about something similar.

    First talking about strings in your example is a distraction, use a struct instead, re-writing it to something like:

    func a() MyStruct {
        /* doesn't matter */
    }
    
    var b *MyStruct = &a()
    

    This won't compile because you can't take the address of a(). So do this:

    func a() MyStruct {
        /* doesn't matter */
    }
    
    tmpA := a()
    var b *MyStruct = &tmpA
    

    This will compile, but you've returned a MyStruct on the stack, allocated sufficient space on the heap to store a MyStruct, then copied the contents from the stack to the heap. If you want to avoid this, then write it like this:

    func a2() *MyStruct {
      /* doesn't matter as long as MyStruct is created on the heap (e.g. use 'new') */
    }
    
    var a *MyStruct = a2()
    

    Copying is normally inexpensive, but those structs might be big. Even worse when you want to modify the struct and have it 'stick' you can't be copying then modifying the copies.

    Anyway, it gets all the more fun when you're using a return type of interface{}. The interface{} can be the struct or a pointer to a struct. The same copying issue comes up.

    0 讨论(0)
提交回复
热议问题