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)
}
Related
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}
}
}
}
For the following code:
package main
import "fmt"
type intFunc func(int) int
var t = func() intFunc {
a := func(b int) int { return b}
return a
}
func main() {
fmt.Println(t()(2))
}
Is there a way to return the pointer to the function instead of the function directly? (something like return &a)?
The playground is here: https://play.golang.org/p/IobCtRjVVX
Yes, as long as you convert the types correctly:
https://play.golang.org/p/3R5pPqr_nW
type intFunc func(int) int
var t = func() *intFunc {
a := intFunc(func(b int) int { return b })
return &a
}
func main() {
fmt.Println((*t())(2))
}
And without the named type:
https://play.golang.org/p/-5fiMBa7e_
var t = func() *func(int) int {
a := func(b int) int { return b }
return &a
}
func main() {
fmt.Println((*t())(2))
}
Accessing other packages:
https://play.golang.org/p/X20RtgpEzqL
package main
import "fmt"
var f = fmt.Println
var p2f = &f
func main() {
(*p2f)("it works")
}
I'm learning Go currently and I made this simple and crude inventory program just to tinker with structs and methods to understand how they work. In the driver file I try to call a method from and item type from the items map of the Cashier type. My method have pointer reciever to use the structs directly instead of making copies. When I run the program I get this error .\driver.go:11: cannot call pointer method on f[0]
.\driver.go:11: cannot take the address of f[0]
Inventory.go:
package inventory
type item struct{
itemName string
amount int
}
type Cashier struct{
items map[int]item
cash int
}
func (c *Cashier) Buy(itemNum int){
item, pass := c.items[itemNum]
if pass{
if item.amount == 1{
delete(c.items, itemNum)
} else{
item.amount--
c.items[itemNum] = item
}
c.cash++
}
}
func (c *Cashier) AddItem(name string, amount int){
if c.items == nil{
c.items = make(map[int]item)
}
temp := item{name, amount}
index := len(c.items)
c.items[index] = temp
}
func (c *Cashier) GetItems() map[int]item{
return c.items;
}
func (i *item) GetName() string{
return i.itemName
}
func (i *item) GetAmount() int{
return i.amount
}
Driver.go:
package main
import "fmt"
import "inventory"
func main() {
x := inventory.Cashier{}
x.AddItem("item1", 13)
f := x.GetItems()
fmt.Println(f[0].GetAmount())
}
The part of the code that really pertains to my problem is the GetAmount function in inventory.go and print statement in the driver.go
A map entry cannot be addressed (as its address might change during map growth/shrink), so you cannot call pointer receiver methods on them.
Detail here: https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/4_pabWnsMp0
As Volker said in his answer - you can't get address of an item in the map. What you should do - is to store pointers to items in your map, instead of storing item values:
package main
import "fmt"
type item struct {
itemName string
amount int
}
type Cashier struct {
items map[int]*item
cash int
}
func (c *Cashier) Buy(itemNum int) {
item, pass := c.items[itemNum]
if pass {
if item.amount == 1 {
delete(c.items, itemNum)
} else {
item.amount--
}
c.cash++
}
}
func (c *Cashier) AddItem(name string, amount int) {
if c.items == nil {
c.items = make(map[int]*item)
}
temp := &item{name, amount}
index := len(c.items)
c.items[index] = temp
}
func (c *Cashier) GetItems() map[int]*item {
return c.items
}
func (i *item) GetName() string {
return i.itemName
}
func (i *item) GetAmount() int {
return i.amount
}
func main() {
x := Cashier{}
x.AddItem("item1", 13)
f := x.GetItems()
fmt.Println(f[0].GetAmount()) // 13
x.Buy(0)
f = x.GetItems()
fmt.Println(f[0].GetAmount()) // 12
}
http://play.golang.org/p/HkIg668fjN
While the other answers are useful, I think in this case it is best just to make non-mutating functions not take a pointer:
func (i item) GetName() string{
return i.itemName
}
func (i item) GetAmount() int{
return i.amount
}
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_
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.