Go (golang) - do method pointers always increment per source definition? - pointers

When methods are defined in Go, does the pointer always increment in the exact order in which they are defined in source - or is it possible that lower pointer space could be re-allocated?
For example - is methods now in the guaranteed order of A, Z, D, B regardless of go version or arch?
package main
import (
"fmt"
"reflect"
"sort"
)
type t struct{}
func (a *t) A() {}
func (a *t) Z() {}
func (a *t) D() {}
func (a *t) B() {}
type addr struct {
Addr uintptr
Method string
}
type addrList []addr
func (a addrList) Len() int {
return len(a)
}
func (a addrList) Less(i, j int) bool {
return a[i].Addr < a[j].Addr
}
func (a addrList) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func main() {
methods := addrList{}
fooType := reflect.TypeOf(&t{})
for i := 0; i < fooType.NumMethod(); i++ {
method := fooType.Method(i)
methods = append(methods, addr{method.Func.Pointer(), method.Name})
}
sort.Sort(methods)
fmt.Println(methods)
}

The Go Programming Language Specification
This is a reference manual for the Go programming language.
The order is not defined in the Go language specification therefore the order is undefined. It's implementation dependent.

Related

Check if underlying type is a struct with reflect

Given this struct
type A struct {
b *B
c string
d string
}
I want to check with reflect which fields have a struct behind the pointer type, so specifically I want to create a condition that would only be true when iterating over field b. From what I've tried using the reflect documentation I always end up with an invalid Value kind which doesn't allow me to go further as every subsequent method panics.
package main
import (
"fmt"
"reflect"
)
type A struct {
b *B
c string
d string
}
type B struct {
}
func main() {
val := reflect.ValueOf(A{})
for i := 0; i < val.Type().NumField(); i++ {
if val.Field(i).Kind() == reflect.Ptr {
fmt.Println(reflect.Indirect(val.Field(i)).Kind())
}
fmt.Println(val.Field(i).Kind())
}
}
https://play.golang.org/p/oRry3ZubRxI
You get invalid value, because the val.b pointer field is nil, and you can't dereference a nil pointer. If you want your code to work, you have to initialize it with a valid pointer:
val := reflect.ValueOf(A{b: &B{}})
With this change it works and outputs (try it on the Go Playground):
struct
ptr
string
If you want it to work without having to initialize the pointer, then you have to work on the types and not values:
val := reflect.ValueOf(A{})
t := val.Type()
for i := 0; i < t.NumField(); i++ {
if ft := t.Field(i).Type; ft.Kind() == reflect.Ptr {
fmt.Println(ft.Elem().Kind())
}
fmt.Println(t.Field(i).Type.Kind())
}
This outputs the same, try this one on the Go Playground.

Indirect of interface type in Go

I'm trying to create a function that will create a new instance of an interface, and assign that instance to a variable that has the type of the interface. Here is a simple example program (which does not compile):
package main
import (
"fmt"
)
type Foo interface {
Foo(int) int
}
type Foo_impl struct {}
func (f *Foo_impl) Foo(x int) int {
return x * 2
}
func main() {
var x *Foo_impl
constructFoo(x)
fmt.Println("Hello, playground")
}
func constructFoo(x Foo) {
*x = Foo_impl{} // Blows up here - invalid indirect of x (type Foo)
}
Is it possible via reflection to indirect an interface variable, and assign to the underlying value? If I were not using interfaces, I would do something like this,
func main() {
var x int
foo(&x)
fmt.Printf("%d\n", x)
}
func foo(x *int) {
*x = 4
}
And as expected, this will print out 4. The issue is that interface variables cannot be indirected in the normal way. Is there a way around this?
But why can't you be more idiomatic and do
func constructFoo() Foo {
return &Foo_impl{}
}
then, in main:
func main() {
fmt.Println(constructFoo().Foo(10))
}
?
Also, there is accept interfaces, return structs approach which may be interesting for you.
Hope this helps a bit.
I was able to write a function that did what I want
package main
import (
"fmt"
"reflect"
)
type Y interface {
SetX(int)
}
type X struct {
test int
}
func (x *X) SetX(param int) {
x.test = param
}
func main() {
var x *X
y := foo(&x)
y.SetX(12)
fmt.Printf("%+v", x)
}
func foo(x interface{}) Y {
t := reflect.TypeOf(x)
pointerType := t.Elem()
realType := pointerType.Elem()
pointer := reflect.New(realType)
reflect.Indirect(reflect.ValueOf(x)).Set(pointer)
return pointer.Interface().(Y)
}
The foo function can initialize any double pointer to a type that implements Y, and it returns the new instance as a Y.
Implementing an interface will help you to pass mock structs to your function and then using type assertion you can get the value of struct. Basically interface is the only way in which you can wrap your any type and pass it to the function and then using type assertions you can get the underlying value.
package main
import (
"fmt"
)
type Foo interface {
Foo(int) int
}
type Foo_impl struct {}
func (f *Foo_impl) Foo(x int) int {
return x * 2
}
func main() {
var x *Foo_impl
constructFoo(x)
}
func constructFoo(x interface{}) {
fmt.Println(x.(interface{}).(*Foo_impl).Foo(10)) // dereference the type to call the function on pointer receiver
}
Also It is required to dereference the value of type struct passed to the constructor to call the method using pointer receiver.
Check working code on Go Playground
In Golang Type assertions is defined as:
For an expression x of interface type and a type T, the primary
expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T.
The notation x.(T) is called a type assertion.
More precisely, if T is not an interface type, x.(T) asserts that the
dynamic type of x is identical to the type T. In this case, T must
implement the (interface) type of x; otherwise the type assertion is
invalid since it is not possible for x to store a value of type T. If
T is an interface type, x.(T) asserts that the dynamic type of x
implements the interface T.
In Go, if we have a type
type Foo_impl struct {}
We usually using
func NewFoo_impl() *Foo_impl
to create this instance of this structure(if need)
There is no instance of the interface, we just say a type implement an interface or not.
So your code can be
var x Foo
x = NewFoo_impl()
// or x = &Foo_impl{}
About indirect the interface type, it's not hard to understand by knowing it just like void* in C.
Dereference it won't return the type you want, in fact, the compiler also doesn't know how to deal with it. It became an incomplete type, so Go's decision is disallowing it.
Here is a solution for your requirements, however a pointer of the type that is being passed to you constructor method can not be nil, one way to address it is to use default instance.
package main
import (
"fmt"
)
var defaultFooImpl = &Foo_impl{}
type Foo interface {
Foo(int) int
}
type Foo_impl struct {
id int
}
func (f *Foo_impl) Foo(x int) int {
return x * 2
}
func main() {
var x *Foo_impl = defaultFooImpl
constructFoo(x)
fmt.Println("Hello, playground %v", x)
}
func constructFoo(x Foo) {
switch value :=x.(type) {
case *Foo_impl:
*value = Foo_impl{2}
}
}
Yet another approach with varadic function that accepts multiple nil pointers to Foo,
package main
import (
"fmt"
)
type Foo interface {
Foo(int) int
}
type Foo_impl struct {
id int
}
func (f *Foo_impl) Foo(x int) int {
return x * 2
}
func main() {
var x *Foo_impl
var x1 = []Foo{x}
constructFoo(x1...)
fmt.Println("Hello, playground %v", x1[0])
}
func constructFoo(x ...Foo) {
for i, foo := range x {
switch (foo).(type) {
case *Foo_impl:
x[i] = &Foo_impl{2}
}
}
}

Method overriding in Go

According to the code below:
type A struct {
}
func (a *A) Func1(i int) {
a.Func2(i)
}
func (a *A) Func2(i int) {
fmt.Println(i)
}
type B struct {
*A
}
func (b *B) Func2(i int) {
i += 1
b.A.Func2(i)
}
func main() {
var b = B{}
b.Func1(1)
}
I have a struct A, and 2 functions Func1, Func2 in A, function A.Func1 will call A.Func2.
And I have another struct B that embedding struct A, and have a function Func2 that overriding A.Func2.
When I declare b that has value B{} and call b.Func1(1), it will run A.Func1 and call A.Func2 but not run A.Func1 and call B.Func2 that I override A.Func2 in B.
My question is how can I fix the code so that when I call b.Func1(1), it will run A.Func1 and call B.Func2 that I override A.Func2 in B.
You are calling promoted method a.Func2(i) using b receiver b.A.Func2(i) type. So in actual it is calling the function with receiver A. Since there is no method overriding in go. Only there are embedded types . So you have to create your version of the same function if you wants your function to be used. Like
func (a *B) Func(i int){
fmt.Println("Calling function from b receiver")
}
can call this in B's Func2
func (b *B) Func2(i int) {
i += 1
b.Func(i)
}
Check this question for more details
Using interface you can get a little bit closer the functionality you want.
type F2 interface {
Func2(i int)
}
func Func1(f2 F2, i int) {
f2.Func2(i)
}
type A struct {
}
func (a *A) Func2(i int) {
fmt.Println(i)
}
type B struct {
*A
}
func (b *B) Func2(i int) {
i += 1
b.A.Func2(i)
}
func main() {
var a = &A{}
Func1(a,1)
var b = &B{}
Func1(b,1)
}

Go improper struct initialization?

While coding I encountered a problem. When I use method of inner struct in goroutine, I can't see inner state like in this code.
package main
import (
"fmt"
"time"
)
type Inner struct {
Value int
}
func (c Inner) Run(value int) {
c.Value = value
for {
fmt.Println(c.Value)
time.Sleep(time.Second * 2)
}
}
type Outer struct {
In Inner
}
func (c Outer) Run() {
go c.In.Run(42)
for {
time.Sleep(time.Second)
fmt.Println(c.In)
}
}
func main() {
o := new(Outer)
o.Run()
}
Program printing:
from inner: {42}
from outer: {0}
from outer: {0}
from inner: {42}
from outer: {0}
from inner: {42}
from outer: {0}
from outer: {0}
Maybe it's pointer problem, but I don't know how resolve it.
The most obvious error in your code is that Inner.Run() has a value-receiver, which means it gets a copy of the Inner type. When you modify this, you modify the copy, and the caller won't see any change on the Inner value.
So first modify it to have a pointer-receiver:
func (c *Inner) Run(value int) {
// ...
}
If a method has a pointer-receiver, the address (pointer) of the value the method is called on will be passed to the method. And inside the method you will modify the pointed value, not the pointer. The pointer points to the same value that is present at the caller, so the same value is modified (and not a copy).
This change alone may make your code work. However, the output of your program is non-deterministic because you modify a variable (field) from one goroutine, and you read this variable from another goroutine too, so you must synchronize access to this field in some way.
One way to synchronize access is using sync.RWMutex:
type Inner struct {
m *sync.RWMutex
Value int
}
When you create your Outer value, initialize this mutex:
o := new(Outer)
o.In.m = &sync.RWMutex{}
Or in one line:
o := &Outer{In: Inner{m: &sync.RWMutex{}}}
And in Inner.Run() lock when you access the Inner.Value field:
func (c *Inner) Run(value int) {
c.m.Lock()
c.Value = value
c.m.Unlock()
for {
c.m.RLock()
fmt.Println(c.Value)
c.m.RUnlock()
time.Sleep(time.Second * 2)
}
}
And you also have to use the lock when you access the field in Outer.Run():
func (c Outer) Run() {
go c.In.Run(42)
for {
time.Sleep(time.Second)
c.In.m.RLock()
fmt.Println(c.In)
c.In.m.RUnlock()
}
}
Note:
Your example only changes Inner.Value once, in the beginning of Inner.Run. So the above code does a lot of unnecessary locks/unlocks which could be removed if the loop in Outer.Run() would wait until the value is set, and afterwards both goroutines could read the variable without locking. In general if the variable can be changed at later times too, the above presented locking/unlocking is required at each read/write.
The simplest way to resolve your issue is to use a pointer receiver in your Run function:
func (c *Inner) Run(value int) {
out = make(chan int)
c.Value = value
for {
fmt.Println(c.Value)
time.Sleep(time.Second * 2)
}
}
But another solution would be to use an out channel to which you can send the Inner struct value:
func (c Inner) Run(value int) {
out = make(chan int)
c.Value = value
for {
fmt.Println(c.Value)
time.Sleep(time.Second * 2)
out <- c.Value
}
}
Then in a separate goroutine to receive back the sent value:
for{
go func() {
c.In.Run(42)
<-out
fmt.Println(out)
}()
time.Sleep(time.Second)
}
Here is the full code:
package main
import (
"fmt"
"time"
)
type Inner struct {
Value int
}
var out chan int
func (c Inner) Run(value int) {
out = make(chan int)
c.Value = value
for {
fmt.Println(c.Value)
time.Sleep(time.Second * 2)
out <- c.Value
}
}
type Outer struct {
In Inner
}
func (c Outer) Run() {
for{
go func() {
c.In.Run(42)
<-out
fmt.Println(out)
}()
time.Sleep(time.Second)
}
}
func main() {
o := new(Outer)
o.Run()
}
https://play.golang.org/p/Zt_NAsM98_

Discover the return type of the current function in go

I have a function that is being generated using reflection and reflect.MakeFunc, so I don't actually have the return type until runtime.
Inside the template function that MakeFunc is using, is there a way to determine the return type of the concrete function being templated?
Essentially, is there a way to determine the return type iof the currently executing function at runtime?
I know about the Out method:
fn.Type().Out(0)
And I can find the return type of a function easily enough?
But is there a way to find the return type of the currently executing function (as opposed to an explicit passed function reference).
You should check fn.Type().Out(0).Kind(), for example:
func main() {
fnTmpl := func(in []reflect.Value) []reflect.Value {
return []reflect.Value{in[0]}
}
makeFn := func(fptr interface{}) {
fn := reflect.ValueOf(fptr).Elem()
fn.Set(reflect.MakeFunc(fn.Type(), fnTmpl))
}
var nFn func(int) int
makeFn(&nFn)
kind := reflect.TypeOf(nFn).Out(0).Kind()
switch kind {
case reflect.Int:
fmt.Println("int")
}
}
In the case you are talking about, the return type of the currently executing function is always []reflect.Type (because that is what a function passed to reflect.MakeFunc must return). What you really want is the return type of the reflect.makeFuncStub function that called your function.
There is no way to get that (except perhaps some strange inspection of the call stack), but you can make an enhanced version of MakeFunc that provides the information:
package main
import (
"fmt"
"reflect"
)
// MakeFunc is like reflect.MakeFunc, but fn has an extra argument, retType, which
// is passed the desired return type.
func MakeFunc(typ reflect.Type, fn func(args []reflect.Value, retType reflect.Type) (results []reflect.Value)) reflect.Value {
if n := typ.NumOut(); n != 1 {
panic("wrong number of return values")
}
rt := typ.Out(0)
return reflect.MakeFunc(typ, func(args []reflect.Value) (results []reflect.Value) {
return fn(args, rt)
})
}
func makeReturnOne(fptr interface{}) {
fn := reflect.ValueOf(fptr).Elem()
fn.Set(MakeFunc(fn.Type(), returnOne))
}
func returnOne(args []reflect.Value, retType reflect.Type) []reflect.Value {
ret := reflect.New(retType).Elem()
switch retType.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
ret.SetInt(1)
case reflect.Float32, reflect.Float64:
ret.SetFloat(1.0)
default:
panic("returnOne only supports int and float types")
}
r := ret.Interface()
fmt.Printf("returning %v as %T\n", r, r)
return []reflect.Value{ret}
}
func main() {
var r1f func() float64
var r1i func() int
makeReturnOne(&r1f)
makeReturnOne(&r1i)
fmt.Println(r1f())
fmt.Println(r1i())
}
I might have misinterpreted what you are trying to achieve, but why not just take the kind of the value you are returning? Modifying OneOfOne's example as follows:
fnTmpl := func(in []reflect.Value) (res []reflect.Value) {
res = []reflect.Value{in[0]}
fmt.Println("Returned:", res[0].Kind())
return res
}
Playground: http://play.golang.org/p/EujmxyGRrI

Resources