golang reflect get closure function pointer - go

please review code
package main
import (
"fmt"
"reflect"
)
func main() {
factory := func (name string) func(){
return func (){
fmt.Println(name)
}
}
f1 := factory("f1")
f2 := factory("f2")
pf1 := reflect.ValueOf(f1)
pf2 := reflect.ValueOf(f2)
fmt.Println(pf1.Pointer(), pf2.Pointer())
fmt.Println(pf1.Pointer() == pf2.Pointer())
f1()
f2()
}
the result:
4199328 4199328
true
f1
f2
Why get to the same address of the closure function!
Or to how to get a unique address!

Function pointers denote the code of the function. And the code of an anonymous function created by function literal is only stored once in memory, no matter how many times the code that returns the anonymous function value runs. This means all function values (or more precisely the function pointers) will be the same.
So you can't distinguish between the values stored in f1 and f2: they denote the same code block to be executed when they are called.
The function value that is returned by the function value stored in your factory variable is a closure. The environment (local variables and function parameters) referred by it survives for as long as it is accessible. In your case this means since the function values in f1 and f2 refer to the name argument of the enclosing anonymous function, they ("they" as from multiple calls) will be retained as long as the function values (in f1 and f2) are accessible. This is the only thing that makes them "different" or unique, but this is invisible from the "outside".
Would you go ahead and print the address of name in the closure, you'd see they are different variables for multiple values of the closure, but it is the same if the same closure (function value) is called again. First modify the closure to also print the address of name:
factory := func(name string) func() {
return func() {
fmt.Println(name, &name)
}
}
And call f1 and f2 multiple times:
f1()
f2()
f1()
f2()
Output:
f1 0x1040a120
f2 0x1040a130
f1 0x1040a120
f2 0x1040a130
As you can see, the name argument is retained and the same name argument is used again if the same closure is invoked again.

https://golang.org/pkg/reflect/#Value.Pointer
If v's Kind is Func, the returned pointer is an underlying code
pointer, but not necessarily enough to identify a single function
uniquely. The only guarantee is that the result is zero if and only if
v is a nil func Value.

Actually, *func() type in Go is equivalent to void (*)(void) type in C. (I know this because I use cgo often.)
And a Go func() is defined as a literal, meaning that it's something like a blob of bytes that represent machine code, rather than a function pointer.
Note that everything is passed by value in Go, and even a function is not an exception.
var f1 func() = ...
reflect.ValueOf(f1)
When you do that, I think you're trying to get the first 8 bytes of a code block called f1, and that is not an address to that function.
In current version of Go you can't take an address of a func() because an anonymous func() is only a literal denoting a code block that's located nowhere in memory. So you can't get an address to that.

Related

Why do we need to copy the value of u here?

I'm a beginner in Go and following an online course where this bit of code was used as an example:
func ConcurrentMutex(url string, fetcher Fetcher, f *fetchState) {
var done sync.WaitGroup
for _, u := range urls {
done.Add(1)
u2 := u
go func() {
defer done.Done()
ConcurrentMutex(u2, fetcher, f)
}()
//go func(u string) {
// defer done.Done()
// ConcurrentMutex(u, fetcher, f)
//}(u)
}
done.Wait()
return
}
The type of u is a string, and the way I see it, we should be able to pass u to the ConcurrentMutex call in the inner function without having to copy its value to u2. However, the professor maintained that the Go memory model meant that as we are continuously changing the value of u, it can affect the different calls to ConcurrentMutex.
I'm still not entirely sure why. Shouldn't the value of u at the point the function is called be passed to the function? I would have understood if we were passing a pointer, but as we're not, it's confusing me.
Can someone please explain how Go's memory model interprets this block?
Note: The commented out inner function was the original one used in the example in the lecture video but was changed in the lecture note. It looks to me like both are equivalent, so I guess the question applies to both.
What you are using is closure. u2 is shared between the inner function and the function surrounding it. Which means with every iteration as u2 is modified, modified value is what is visible to inner function. Better way of writing is using the code that has been commented out. By explicitly passing a value to go routine, you ensure that go routine carries it's own copy that will not be modified by surrounding function.
What go specification says about this: Go specification
Function literals A function literal represents an anonymous function.
FunctionLit = "func" Signature FunctionBody . func(a, b int, z
float64) bool { return a*b < int(z) } A function literal can be
assigned to a variable or invoked directly.
f := func(x, y int) int { return x + y } func(ch chan int) { ch <- ACK
}(replyChan) 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.
Hope this answers your question.

Why Value To Variable X Increasing In Function?

I am unable to understand to why value of x increase even after scope end for varaiable ‘x’ in function foo(). It’s must reset to zero everytime I called a function. This this not happening why?
package main
import "fmt"
func main() {
a := foo()
fmt.Printf("%d\n", a())
fmt.Printf("%d\n", a())
fmt.Printf("%d\n", a())
}
func foo() func() int {
var x int // value should reset to zero
return func() int {
x++
return x
}
}
Go Playground
Your function foo returns a new function each time it's called. foo doesn't just create that function though, it also allocates memory for a variable called x of type int. That variable is declared in the scope of foo, and as such, the function foo returns has access to that variable.
In essence, you're returning what is often referred to as a closure. A function that has access to a scope (variables) that are invisible to any other code. To visually represent this, maybe thing of it like this:
The function is what you return, the "environment record" it holds on to is the function body of foo, and all of the variables declared there (in your case x). The next environment record would be the package (variables declared outside functions with var).
So what happens exactly:
a := foo()
Here, foo allocates variable x, and returns a function that holds on to this new variable.
a() // returns 1
a() // returns 2
The x variable created by foo is incremented, and its new value is returned each time.
Now that you know this, you should be able to work out what the output here will be:
a, b := foo(), foo() // creates 2 functions, 2 variables called x
_ = a()
_ = a()
fmt.Printf("a call returned %d\nb call returned %d\n", a(), b())
The output should be "a call returned 3 b call returned 1"

How to understand this behavior of goroutine?

package main
import (
"fmt"
"time"
)
type field struct {
name string
}
func (p *field) print() {
fmt.Println(p.name)
}
func main() {
data := []field{ {"one"},{"two"},{"three"} }
for _,v := range data {
go v.print()
}
<-time.After(1 * time.Second)
}
why does this code print 3 "three" instead of "one" "two" "three" in any order?
There is a data race.
The code implicitly takes address of variable v when evaluating arguments to the goroutine function. Note that the call v.print() is shorthand for the call (&v).print().
The loop changes the value of variable v.
When goroutines execute, it so happens that v has the last value of the loop. That's not guaranteed. It could execute as you expected.
It's helpful and easy to run programs with the race detector. This data race is detected and reported by the detector.
One fix is to create another variable scoped to the inside of the loop:
for _, v := range data {
v := v // short variable declaration of new variable `v`.
go v.print()
}
With this change, the address of the inner variable v is taken when evaluating the arguments to the goroutine. There is a unique inner variable v for each iteration of the loop.
Yet another way to fix the problem is use a slice of pointers:
data := []*field{ {"one"},{"two"},{"three"} } // note '*'
for _, v := range data {
go v.print()
}
With this change, the individual pointers in the slice are passed to the goroutine, not the address of the range variable v.
Another fix is to use the address of the slice element:
data := []field{ {"one"},{"two"},{"three"} } // note '*'
for i:= range data {
v := &data[i]
go v.print()
}
Because pointer values are typically used with types having a pointer receiver, this subtle issue does not come up often in practice. Because field has a pointer receiver, it would be typical to use []*field instead of []field for the type of data in the question.
If the goroutine function is in an anonymous function, then a common approach for avoiding the issue is to pass the range variables as an argument to the anonymous function:
for _, v := range data {
go func(v field) {
v.print() // take address of argument v, not range variable v.
}(v)
}
Because the code in the question does not already use an anonymous function for the goroutine, the first approach used in this answer is simpler.
As stated above there’s a race condition it’s result depends on delays on different processes and not well defined and predictable.
For example if you add time.Sleep(1*time.Seconds) you likely to get a correct result. Because usually goroutine prints faster than 1second and will have correct variable v but it’s a very bad way.
Golang has a special race detector tool which helps to find such situations. I recommend read about it while reading testing. Definitely it’s worth it.
There’s another way - explicitly pass variable value at goroutine start:
for _, v := range data {
go func(iv field) {
iv.print()
}(v)
}
Here v will be copied to iv (“internal v”) on every iteration and each goroutine will use correct value.

go for range slice and goroutine method invocation,the logic behind

The code is like the following:
package main
import (
"fmt"
"time"
)
type field struct {
name string
}
func (p *field) print() {
fmt.Println(p.name)
}
func main() {
data := []field{{"one"},{"two"},{"three"}}
for _,v := range data {
go v.print()
}
time.Sleep(3 * time.Second)
}
I know that the code is wrong,because the for loop variable is reused in the for-range loop.
When the goroutine has got the chance to launch,the value of v might has been modified. so the print result will be "three,three,three".
But when we modify the data variable into another declaration as:
data := []*field{{"one"},{"two"},{"three"}}
the print result will be "one ,two,three".
I didn't get the point of why. Does the pointer make any difference or any different mechanism is on this?
I read this from this article. But the poster didn't not tell why. Or it's just a incident the output is right.
In the first loop, v is the value of a field item. Because v is addressable, it is automatically referenced as the pointer receiver for the print() method. So v.print() is using the address of v itself, and the contents of that address is overwritten each iteration of the loop.
When you change the declaration to use a *field, v is now a pointer to a field value. When you call v.print() in this case, you are operating on the value that v points to, which is stored in data, and the overwriting of v has no effect.

golang function with leading "type ***"

type ApplyFunc func(commitIndex uint64, cmd []byte) []byte
For this declaration. My understanding is,this is a function pointer. Its name is ApplyFunc.
And this function takes commitIndex and cmd as inputs. It returns []byte.
Is my understanding right?
thanks!
Golang function are first-class, as illustrated in this go-example page.
It is a named type, which means you can use ApplyFunc anywhere where a func(commitIndex uint64, cmd []byte) []byte is expected: see "Golang: Why can I type alias functions and use them without casting?".
It means, as commented by Volker, it isn't a function or a "pointer to a function".
It is a type which allows you to declare a variable storing any function which respects the same func signature as its declared type, like a function literal (or "anonymous function").
var af ApplyFunc = func(uint64,[]byte) []byte {return nil}
// (function literal or "anonymous function")
See "Anonymous Functions and Closures": you can define a function which returns another function, taking advantage of 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.
(see playground example)
type inc func(digit int) int
func getIncbynFunction(n int) inc {
return func(value int) int {
return value + n
}
}
func main() {
g := getIncbynFunction
h := g(4)
i := g(6)
fmt.Println(h(5)) // return 5+4, since n has been set to 4
fmt.Println(i(1)) // return 1+6, since n has been set to 6
}
Also, As illustrated in "Golang function pointer as a part of a struct", you can define functions on a func receiver ApplyFunc(!).

Resources