在 Go 中,是否可以定义一个本地变量,使其能够在一个函数调用和另一个函数调用之间保持其值?在 C 中,我们可以使用保留字 static
来实现这一点。
C 语言示例:
int func() {
static int x = 0;
x++;
return x;
}
在 Go 中,是否可以定义一个本地变量,使其能够在一个函数调用和另一个函数调用之间保持其值?在 C 中,我们可以使用保留字 static
来实现这一点。
C 语言示例:
int func() {
static int x = 0;
x++;
return x;
}
使用闭包:
函数字面量是闭包:它们可以引用在周围函数中定义的变量。这些变量随后在周围函数和函数字面量之间共享,并且只要它们可访问,它们就会一直存在。
它不必在全局范围内,只需在函数定义外部即可。
func main() {
x := 1
y := func() {
fmt.Println("x:", x)
x++
}
for i := 0; i < 10; i++ {
y()
}
}
(在Go Playground上的示例)
你可以像这样做
package main
import (
"fmt"
)
func main() {
f := do()
f() // 1
f() // 2
}
func do() (f func()){
var i int
f = func(){
i++
fmt.Println(i)
}
return
}
f()
,这应该会引起问题。两个线程可以通过do()
实例化自己的函数,然后调用它们将是线程安全的,因为它们操作不同的资源。但是,这个问题显然可以用更简单的方法解决。这里的问题是创建一个始终在相同一组资源上运行的单个函数,这肯定从定义上来说是不可能线程安全的。不过,你提到的单元测试也很有道理。 - Alexander Guyer在全局范围内声明一个变量:
var i = 1
func a() {
println(i)
i++
}
在下面的例子中,变量sum对于每个闭包a1和a2都像是一个单独的静态变量。
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
a1,a2 := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
a1(i),
a2(-1*i),
)
}
}
输出
0 0
1 -1
3 -3
6 -6
10 -10
15 -15
21 -21
28 -28
36 -36
45 -45
像Taric的建议一样,但是staticCounter()返回一个int函数
package main
import (
"fmt"
)
func staticCounter() (f func()(int)){
var i int
f = func()(int){
i++
// fmt.Println(i)
return i
}
return
}
func main() {
f := staticCounter()
g := staticCounter()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(g())
fmt.Println(g())
}
var myFunction = func() func(type1, type2) type3 {
myStaticVariable := []string {"hello", "world"}
return func(arg1 type1, arg2 type2) type3 {
// use arg1, arg2 and myStaticVariable here
}
}()
// A var x1 is local to main(), is not a global var.
// A static var is one that can't be accesed from others functions just
// like global vars.
// A static var dont disappears when the function ends.
// So is what x1 n x2 are pretending in this program.
package main
import (
"fmt"
)
/*
int func() { // x static inside a function.
static int x = 0;
x++;
return x;
}
*/
//
func main() {
//
var x1 int = 0
var x2 int = 100
//
for i := 0; i < 10; i++ { // call to a "static" var x
x1 = fun1(&x1)
x2 = fun2(&x2)
fmt.Printf("%d %d \n", x1, x2)
} //
test1(x1, x2) // a funct needs parameters to see x1 n x2
} //main
//
func fun1(p *int) int {
//
*p++ // save value
return *p //counter x1
}
//
func fun2(p *int) int {
*p++ // save value
return *p //counter x2
}
//
func test1(x1 int, x2 int) {
fmt.Println("\"x1\" y \"x2\" ", x1, x2)
}