duanjian7617 2015-03-03 06:14
浏览 31
已采纳

在golang中,如何在函数中重新分配外部引用?

I'm probably not expressing this correctly in the question, but perhaps this code will make it clearer:

package main
import "fmt"

type Blob struct {
    Message string
}

func assign1(bb **Blob) {
    *bb = &Blob{"Internally created by assign1"}
}

func (b *Blob) assign2() {
    *b = Blob{"Internally created by assign2"}
}

func main() {
    x1 := &Blob{"Hello World"}
    assign1(&x1)
    fmt.Printf("x1 = %+v
", *x1)

    x2 := Blob{"Hello World"}
    x2.assign2()
    fmt.Printf("x2 = %+v
", x2)
}

Produces, as desired:

x1 = {Message:Internally created by assign1}
x2 = {Message:Internally created by assign2}

I want to pass a reference (pointer to a pointer) into a function and have the function assign a new value to the pointer such that the calling scope will see that new value.

I've figured out the above two ways of doing this, but I'd like to know if they are actually correct or if there is some hidden flaw. Also, are either of them more idiomatic than the other?

Coming from Java, assign2 just seems wrong but I'm sure I've seen something similar in the encoding/json package. What is that actually doing?

Thanks!

  • 写回答

2条回答 默认 最新

  • doutao4938 2015-03-03 07:11
    关注

    James answers the mechanics of assign2. I'll touch a bit on when to use it.

    Let's take a simpler example, first.

    type Counter uint
    
    func (c *Counter) Increment() {
        *c += 1
    }
    

    In the counter example the entire state of the receiver is changing. Similarly for the encoding/json package the entire state of the receiver is changing. That's really the only time I would use that style.

    One major advantage of the style: you can define an interface for the change, just like the GobDecoder does.

    When I first saw the assign2 style it was a little grating. But then I remembered that (c *Counter) Increment gets translated to Increment(c *Counter) in the machine code and it didn't bother me anymore. I personally prefer assign1-style. (Though, there is no need for the double pointers as orignally posted.)

    package main
    import "fmt"
    
    type Blob struct {
        Message string
    }
    
    func assign1(b *Blob) {
        *b = Blob{"Internally created by assign1"}
    }
    
    func main() {
        x1 := Blob{"Hello World"}
        assign1(&x1)
        fmt.Printf("x1 = %+v
    ", *x1)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题