Indirect of interface type in Go - pointers

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}
}
}
}

Related

How to modify interface value of type struct pointer

So I have some interfaces and structs:
type Component interface{}
type Position struct{
x float64
}
func Main(){
var components []Components
components = append(components, &Position{1.0})
pos := components[0] // this is a Component, however reflect.TypeOf() returns *Position
*pos = Position{2.0} // this won't compile as golang says you can't dereference a 'Component'
}
How would I modify the actual value (e.g. change 'x') inside the pos variable one I retrieved it? I am storing these pointers in a Component slice as there are various types that implement components.
I have tried doing this:
func Swap(component *Component, value Component){
*component = value
}
however this does not work (it runs however the new value is not udpated). How do I dereference the component and assign its value?
You should use type assertions:
package main
import (
"fmt"
)
type Component interface{}
type Position struct {
x float64
}
func (p Position) String() string {
return fmt.Sprintf("%f", p.x)
}
func main() {
components := []Component{&Position{1.0}}
fmt.Println(components)
pos, ok := components[0].(*Position)
if !ok {
panic("Not a *Position")
}
pos.x = 1000.0
fmt.Println(components)
}
This prints:
[1.000000]
[1000.000000]
If you need to check for multiple types, you could use a type switch.

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

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.

How to extract the interface type name and package using reflection?

I need to know the type name and its path using reflection. type Type has a Name() and PkgPath() method but both of them return empty if the type is an interface.
However if I reflect a function and extract the type information of its arguments I get the correct type information. Should I assume it's a bug in the former case? Shouldn't TypeOf return the same type information regardless the context(e.g. type function parameter or type of a value) ?
I'm aware of type assertion but I don't always have a value to do the assertion so I need to work with reflect.Type information.
package main
import (
"fmt"
"reflect"
"golang.org/x/net/context"
)
func main() {
c := reflect.TypeOf(withValue(""))
fn := func(context.Context){}
fc := reflect.TypeOf(fn).In(0)
fmt.Println(isContext(c), isContext(fc), c, fc)
}
func isContext(r reflect.Type) bool {
return r.PkgPath() == "golang.org/x/net/context" && r.Name() == "Context"
}
func withValue(v interface{}) context.Context {
return context.WithValue(context.TODO(), "mykey", v)
}
Prints
false true *context.valueCtx context.Context
Here is some working code: https://play.golang.org/p/ET8FlguA_C
package main
import (
"fmt"
"reflect"
)
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (ms *MyStruct) MyMethod() {}
func main() {
var structVar MyInterface = &MyStruct{}
c := reflect.TypeOf(structVar)
fn := func(MyInterface) {}
fc := reflect.TypeOf(fn).In(0)
fmt.Println(isMyInterface(c), isMyInterface(fc), c, fc)
// OP expects : "true true main.MyInterface main.MyInterface"
}
func isMyInterface(r reflect.Type) bool {
// TypeOf trick found at https://groups.google.com/forum/#!topic/golang-nuts/qgJy_H2GysY
return r.Implements(reflect.TypeOf((*MyInterface)(nil)).Elem())
}
Here is my answer before I found an actual solution with reflect.
I'm gonna let it here because I think it still has some interesting parts.
First things first: for c, r.PkgPath() and r.Name() are empty because the underlying type is a pointer (*context.valueCtx).
To fix that, you can use c := reflect.Indirect(reflect.ValueOf(withValue(""))).Type()
But that does not make isContext(c) true, because you then have r.PkgPath() == "golang.org/x/net/context" && r.Name() == "valueCtx".
The best way to check if a var implements an interface is to drop the reflection and use a type assertion like this:
https://play.golang.org/p/td1YaHHej9
package main
import "fmt"
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (ms *MyStruct) MyMethod() {}
func main() {
var structVar MyInterface = &MyStruct{}
fmt.Println(isMyInterface(structVar))
}
func isMyInterface(object interface{}) bool {
_, ok := object.(MyInterface)
return ok
}
Your code works as you expect with the function parameter because there is no underlying value, so reflect uses the interface type. But for any concrete var, it will use the actual type of the value.
There are two kinds of Interface in golang, aka, eface and iface. And the eface is an empty interface, which can simply represented as interface {}. The iface is kind of interface which has at least one method, such as:
type MyInterface interface {
Greeting() string
}
In golang implementation, both eface and iface are two-word long struct. The eface holds the data and the data type, the iface holds the data, the interfacetype and the data type. When an iface assigned to an eface, the interfacetype information is ignored. Only the data and the data type passed to the eface.
So, reflect.TypeOf(i interface{}) 's parameter is and eface, no interfacetype information (aka context.Context in your case). So you can't get the original interfacetype.

Declaring map with function pointer value in goLang

I'd like to declare a map that would that would look like this, so I could map various init functions to initType:
func makeMap(){
m := make(map[initType]&InitFunc)
//How should the value declaration be set up for this map?
}
type initType int
const(
A initType = iota
B
C
D
)
func init(aInitType initType){
doStuff(aInitType)
}
func init(aInitType initType){
doOtherStuff(aInitType)
}
func init(aInitType initType){
doMoreStuff(aInitType)
}
How do I declare the function pointer type (which I called &InitFunc in the example because I don't know how to do it) so I can use it as the value in a Map?
Unlike C, you don't actually need a "pointer" to the function, since in Go, functions are reference types, similar to slices, maps, and channels. Further, the address operator, &, produces a pointer to a value, but to declare a pointer type, use *.
You seem to be wanting your InitFunc to take a single InitType and return no values. In that case, you would declare it as:
type InitFunc func(initType)
Now, your map initialization can simply look like:
m := make(map[initType]InitFunc)
A complete example would be (http://play.golang.org/p/tbOHM3GKeC):
package main
import "fmt"
type InitFunc func(initType)
type initType int
const (
A initType = iota
B
C
D
MaxInitType
)
func Init1(t initType) {
fmt.Println("Init1 called with type", t)
}
var initFuncs = map[initType]InitFunc{
A: Init1,
}
func init() {
for t := A; t < MaxInitType; t++ {
f, ok := initFuncs[t]
if ok {
f(t)
} else {
fmt.Println("No function defined for type", t)
}
}
}
func main() {
fmt.Println("main called")
}
Here, it's looping through each initType, and calling the applicable function, if it is defined.

How can I type select an interface on a pointer-to-pointer in Go?

I have a pair of interfaces defined like so:
type Marshaler interface {
Marshal() ([]byte, error)
}
type Unmarshaler interface {
Unmarshal([]byte) error
}
I have a simple type which implement these:
type Foo struct{}
func (f *Foo) Marshal() ([]byte, error) {
return json.Marshal(f)
}
func (f *Foo) Unmarshal(data []byte) error {
return json.Unmarshal(data, &f)
}
I am using a library which defines a different interface, and implementing it like so:
func FromDb(target interface{}) { ... }
The value being passed for target is a pointer to pointer:
fmt.Println("%T\n", target) // Prints **main.Foo
Typically this function does a type switch and then operates on the type underneath. I would like to have common code for all types that implement my Unmarshaler interface but can't figure out how to get from a pointer-to-pointer of a specific type to my interface.
You cannot define methods on a pointer to a pointer:
func (f **Foo) Unmarshal(data []byte) error {
return json.Unmarshal(data, f)
}
// compile error: invalid receiver type **Foo (*Foo is an unnamed type)
You cannot define receiver methods on pointer types:
type FooPtr *Foo
func (f *FooPtr) Unmarshal(data []byte) error {
return json.Unmarshal(data, f)
}
// compile error: invalid receiver type FooPtr (FooPtr is a pointer type)
Casting to Unmarshaler doesn't work:
x := target.(Unmarshaler)
// panic: interface conversion: **main.Foo is not main.Unmarshaler: missing method Unmarshal
Casting to *Unmarshaler doesn't work either:
x := target.(*Unmarshaler)
// panic: interface conversion: interface is **main.Foo, not *main.Unmarshaler
How can I get from this pointer-to-pointer type to my interface type without needing to switch on every possible implementor type?
It's ugly, but is is possible to have the semantic equivalent of a pointer to pointer receiver. For example:
package main
import "fmt"
type P *int
type W struct{ p P }
func (w *W) foo() {
fmt.Println(*w.p)
}
func main() {
var p P = new(int)
*p = 42
w := W{p}
w.foo()
}
Playground
Output:
42
Note that
fmt.Println(*w.p)
above is actually
fmt.Println(*(*w).p)
where the extra work is done for you by the compiler automagically.
If target is a **Foo and *Foo implements Unmarshaler, you can do:
var x Unmarshaler = *target
If target is a an interface{} containing a **Foo, this would work instead:
var x Unmarshaler = *(target.(**Foo))
It's a similar idea if you have a type switch.
Whenever I have to deal with pointer-to-pointer or pointer-to-reference, the variable life-time is generally pretty short and they quickly go back to being a single pointer (or plain reference) again.
I'd evaluate whether the pointer-to-pointer is indeed required for the use case at hand or whether you can do something like that.

Resources