我在Go这里找到了一个闭包的例子: https://gobyexample.com/closures
它提供了一个非常简单的Go中闭包范围的例子。我改变了如何从“i:= 0”初始化为“i:= * new(int)”。
func intSeq() func() int {
i := *new(int)
return func() int {
i += 1
return i
}
}
func main() {
// We call `intSeq`, assigning the result (a function)
// to `nextInt`. This function value captures its
// own `i` value, which will be updated each time
// we call `nextInt`.
nextInt := intSeq()
// See the effect of the closure by calling `nextInt`
// a few times.
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
// To confirm that the state is unique to that
// particular function, create and test a new one.
newInts := intSeq()
fmt.Println(newInts())
}
这个输出仍然是1,2,3,1。每次调用main()中的nextInt()时,intSeq()中的变量'i'是否都不会被重新分配?
答案 0 :(得分:3)
了解您如何实施intSeq
。
func intSeq() func() int {
i := *new(int)
return func() int {
i += 1
return i
}
}
i
的初始化超出了它返回的函数。
因此,分配新指针的唯一时间是实际调用intSeq
。
由于你只做了两次,这就是你得到了多少不同的指针。
这解释了为什么在你只是调用nextInt
时没有重置该值(请注意,执行nextInt
意味着只执行返回的函数,如下所示:
func() int {
i += 1
return i
}
这不会重置i
的值,而是继续增加它(直到你再次调用intSeq
创建一个新值)。
我希望澄清。
答案 1 :(得分:2)
不,它没有。这就是结束的关键。您正在初始化一个整数变量并将其存储在堆上,以供intSeq()
函数返回的函数使用。 nextInt()
函数
您将获得一个新函数,该函数使用从0开始的新序列计数器,每次调用intSeq()
编辑:要添加到此,这是获取当前行为的一种不好的方法。更好的方法是创建包含方法sequence
的新nextInt() int
类型。 E.g:
type Sequence struct {
counter int
}
func (s *Sequence) nextInt() int {
s.counter++
return s.counter
}
func main() {
intSeq := new(Sequence)
fmt.Println(intSeq.nextInt())
fmt.Println(intSeq.nextInt())
fmt.Println(intSeq.nextInt())
}
答案 2 :(得分:0)
执行i := *new(int)
没有意义。那条线说:
int
i
这与i := 0
或var int i
没什么区别,但是在创建,解除引用和丢弃永不使用的指针的过程中还有一个额外的步骤。
如果需要指向int的指针,请使用i := new(int)
。 *new
任何地方都是无意义的调用和代码味道。