【问题标题】:Is there any problem if I hold a member function pointer out of the pointer instance scope如果我将成员函数指针置于指针实例范围之外,是否有任何问题
【发布时间】:2020-03-31 07:50:48
【问题描述】:
type A struct {
    x1 []int
    x2 []string
}
func (this *A) Test() {
    fmt.Printf("this is: %p, %+v\n", this, *this)
}
func main() {
    var fn func()
    {
        a := &A{}

        a.x1 = []int{1, 2, 3}
        a.x2 = []string{"one", "two", "three"}
        fn = a.Test
    }

    fn()
}

请看:https://play.golang.org/p/YiwHG0b1hW-

我的问题是:

  1. 是否会在 {} 本地范围之外发布“a”?
  2. “a”的生命周期是否等于“fn”的生命周期?

【问题讨论】:

  • 这是一种创建闭包的迂回方式。闭包在 Go 中运行良好。
  • 此外,正如您所证明的,它在操场上工作的事实回答了您自己的问题。

标签: pointers go member-functions


【解决方案1】:

Go 是一种垃圾收集语言。只要您不触摸包unsafe(或类似Value.UnsafeAddr() 中的reflect 包),只要它们可以访问,所有值都会保留在内存中。您不必担心内存管理。

这就是为什么返回在函数内部创建的局部变量的地址(指针)也是安全的。而且从函数值(闭包)中引用局部变量也是安全的,当函数值在未来某个时间执行时,这些局部变量将超出范围,比如这个:

func counter() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}

这个counter() 返回一个函数(闭包),当调用它时,返回递增的值:

c := counter()
fmt.Println(c())
fmt.Println(c())
fmt.Println(c())

这个输出(在Go Playground上试试):

1
2
3

counter() 创建一个不返回的局部变量i,而是从它返回的函数值访问。只要返回的函数值是可访问的,就不会释放局部变量i。此外,如果您再次调用 counter(),则会创建一个与前一个不同的新 i 变量。

查看相关问题:

How to delete struct object in go?

Cannot free memory once occupied by bytes.Buffer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多