Static local variable in Go - go

Is it possible to define a local variable in Go that can maintain its value from one function call to another? In C, we can do this using the reserved word static.
Example in C:
int func() {
static int x = 0;
x++;
return x;
}

Use a closure:
Function literals are closures: they may refer to variables defined in
a surrounding function. Those variables are then shared between the
surrounding function and the function literal, and they survive as
long as they are accessible.
It doesn't have to be in global scope, just outside the function definition.
func main() {
x := 1
y := func() {
fmt.Println("x:", x)
x++
}
for i := 0; i < 10; i++ {
y()
}
}
(Sample on the Go Playground)

You can do something like this
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
}
Link on Playground https://play.golang.org/p/D9mv9_qKmN

Declare a var at global scope:
var i = 1
func a() {
println(i)
i++
}

Like Taric' suggestion, but with staticCounter() returning an int function
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())
}

Use Function closure
In following example, variable sum behaves like a separate static for each closure a1 and 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),
)
}
}
Output
0 0
1 -1
3 -3
6 -6
10 -10
15 -15
21 -21
28 -28
36 -36
45 -45

In all the other answers, the function containing a static variable is assigned in the main.
Here is how you can define and assign that function in the global scope.
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)
}

Related

Calling function names from a slice and return a value

I want to call a number of function names stored in a slice. The code snippet below works so far but I need to return a value from those functions. Unfortunately I don't get it to work because I don't know to to call those functions and store the return value. Any ideas?
This is the code I'm currently working on:
package main
func A(x int) int {
return x + 1
}
func B(x int) int {
return x + 2
}
func C(x int) int {
return x + 3
}
func main() {
x := 10
type fs func(x int) int
f := []fs{A, B, C}
fns := make([]func(), 3)
for a, _ := range f {
a := a
fns[a] = func() {
f[a](x)
}
}
for _, f := range fns {
f()
}
}
Go Playground
You have call it...
for a, _ := range f {
a := a
fns[a] = func() {
f[a](x) // in this
}
}
here is the playground

Convert *_Ctype_float into float32 in Go

I am new to Go and having difficulty in converting the *_Ctype_float datatype into []float32. Is there something that I am missing? I even thought of converting *_Ctype_float into string but even that was not successful.
I have this C function named predictInstance which returns float*. I am calling this function from Go by
predictionValues := C.predictInstance(
handle,
(*C.float)(unsafe.Pointer(&req.FlatInput[0])),
)
Now when I look at the type of predictionValues it says it is *Ctype_float. Now I want to convert this into []float32
I have a C function which returns a float* array which I wish to convert to []float32. I am calling this
function from Go with a float* array argument.
A working example,
package main
/*
#include <stdlib.h>
#include <float.h>
float *reverse(float *f, int len) {
float *g = calloc(len, sizeof(float));
for (int i = 0; i < len; i++) {
g[i] = f[len-1-i];
}
return g;
}
*/
import "C"
import (
"fmt"
"math"
"unsafe"
)
func main() {
a := []float32{3.14159, 2.718, 1}
r := make([]float32, len(a))
fmt.Println("a:", a, "r:", r)
c := C.reverse((*C.float)(&a[0]), C.int(len(a)))
copy(r, (*[1 << 20]float32)(unsafe.Pointer(c))[:])
C.free(unsafe.Pointer(c))
fmt.Println("a:", a, "r:", r)
}
var okCFloat = func() bool {
if C.sizeof_float != unsafe.Sizeof(float32(0)) {
panic("C float != Go float32")
}
if C.FLT_MAX != math.MaxFloat32 {
panic("C float != Go float32")
}
return true
}()
Output:
a: [3.14159 2.718 1] r: [0 0 0]
a: [3.14159 2.718 1] r: [1 2.718 3.14159]

Go closure with naked return

I am playing around with Go and am trying to implement a fibonacci function that returns a closure that returns fibonacci numbers. The problem can be found in the go tool tour. Here is a closure implementation that uses a regular (non-naked) return:
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a := 0
b := 1
return func() int {
t := a + b
a = b
b = t
return b
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
The function correctly returns the following:
1
2
3
5
8
13
21
34
55
89
I tried writing the fibonacci function differently by trying to use a naked return within the closure function, but it produces an error:
./compile20.go:9:7: b declared and not used
Here is the code that generates the error
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a := 0
b := 1
return func() (b int) {
t := a + b
a = b
b = t
return
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Anybody know how the variable b is not being used? b is obviously used in the first line of the closure function (t := a + b).
Variables defined in the return segment shadow the variable with the same name in the outer scope. Inside your returned function, b refers to the one defined in the return value.
You can remove the first declaration (and initialization) of b and the program passes the check, although the logic is not right.
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a := 0
b := 1 // declare a variable b and initialize with 1
return func() (b int) { // declare a variable b with default initialization
t := a + b // b refers to the variable defined in the return value
a = b
b = t
return
}
}

Indirectly change a value in a struct in Go

I have the following code, feel free to offer pointers if you wish:
package main
import (
"fmt"
)
type Grid struct {
rows int
cols int
tiles []Tile
}
type Tile struct {
x int
y int
contents int
}
func (g Grid) AddTile(t Tile) {
g.tiles = append(g.tiles, t)
}
func (g *Grid) Row(num int) []Tile {
numTiles := len(g.tiles)
row := []Tile{}
for i := 0; i < numTiles; i++ {
tile := g.tiles[i]
if (tile.y == num) {
row = append(row, tile)
}
}
return row
}
/*
HERE IS WHERE I NEED HELP
*/
func (g *Grid) SetRow(num, val int) {
row := g.Row(num)
rowLength := len(row)
for i := 0; i < rowLength; i++ {
tile := &row[i]
tile.contents = val
}
}
func (g Grid) Col(num int) []Tile {
numTiles := len(g.tiles)
col := []Tile{}
for i := 0; i < numTiles; i++ {
tile := g.tiles[i]
if (tile.x == num) {
col = append(col, tile)
}
}
return col
}
func MakeTile(x, y int) Tile {
tile := Tile{x: x, y: y}
return tile
}
func MakeGrid(rows, cols int) Grid {
g := Grid{ rows: rows, cols: cols}
for r := 1; r <= rows; r++ {
for c := 1; c <= cols; c++ {
g.tiles = append(g.tiles, MakeTile(r, c))
}
}
return g
}
func main() {
g := MakeGrid(256, 256)
g.SetRow(100, 5)
fmt.Println(g.Row(100))
}
I am doing this, more than anything, as a simple project to help me learn Go. The problem that is have run in to is here
/*
HERE IS WHERE I NEED HELP
*/
func (g *Grid) SetRow(num, val int) {
row := g.Row(num)
rowLength := len(row)
for i := 0; i < rowLength; i++ {
tile := &row[i]
tile.contents = val
}
}
Somewhere it seems like I need to be making a pointer to the actual Tiles that I'm trying to modify. As it is the SetRow function doesn't actually modify anything. What am I doing wrong? Keep in mind I just started learning Go 2 days ago, so this is a learning experience :)
One way to accomplish your goal is to use pointers to tiles throughout the code. Change the Grid tiles field to:
tiles []*Tile
and several related changes through the code.
Also, change all the methods to use pointer receivers. The AddTile method as written in the question discards the modification to the grid on return.
playground example

Go — declared and not used error, when I think I have done so to the variable

What's wrong with this code?
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
prev := 0
curr := 1
return func() int {
temp := curr
curr := curr + prev
prev := temp
return curr
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
prog.go:13: prev declared and not used
You declared a variable named prev and then never used it.
Specifically, you said prev := temp. This is creating a new local variable in the current scope named prev. I assume you meant to just say prev = temp, which modifies the prev variable inherited from the surrounding scope. Similarly you probably meant to say curr = curr + prev on the previous line, instead of using :=.
If you make the changes suggested by Kevin Ballard, then,
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
prev := 0
curr := 1
return func() int {
temp := curr
curr = curr + prev
prev = temp
return curr
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Output:
1
2
3
5
8
13
21
34
55
89
The output is not the Fibonacci sequence.
For the Fibonacci sequence,
package main
import "fmt"
func fibonacci() func() int {
a, b := 0, 1
return func() (f int) {
f, a, b = a, b, a+b
return
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Output:
0
1
1
2
3
5
8
13
21
34

Resources