Go Gotcha
package main

import "fmt"

type Foo struct {
  x int
}

func (f Foo) foo1() {
  fmt.Println("foo1")
}

func (f *Foo) foo2() {
  fmt.Println("foo2")
}

type InterfaceFoo1 interface {
  foo1()
}

type InterfaceFoo2 interface {
  foo2()
}

func useFoo1(m InterfaceFoo1) {
  fmt.Printf("the type is: %T\n", m)
  m.foo1()
}

func useFoo2(m InterfaceFoo2) {
  fmt.Printf("the type2 is: %T\n", m)
  m.foo2()
}

func useFoo3(m *InterfaceFoo2) {
  fmt.Printf("the type3 is: %T\n", m)
  (*m).foo2()  // must be (*m), can't be m.foo2()
}

func f1(f Foo) {
  fmt.Println(f.x)
}

func f2(f *Foo) {
  fmt.Println(f.x)
}

func main() {
  fmt.Println("Hello, playground")
  z:=Foo{x:3}
  f1(z)

 // f2(z)

  y:=&Foo{x:4}
  f2(y)     
 // f1(y)

  useFoo1(z)    
  useFoo2(y)     
  useFoo1(y)    
//  useFoo2(z)    

  var ip1 InterfaceFoo1 = z 
  useFoo1(ip1)

  var ip11 InterfaceFoo1 = y 
  useFoo1(ip11)

  var ip2 InterfaceFoo2 = y        
  useFoo2(ip2)        

 // var ip222 * InterfaceFoo2 = y      not ok

  var ip22 InterfaceFoo2 = &z      // z not ok, because the receiver is * ..
  useFoo2(ip22)

  useFoo3(&ip22)                
}

out put

package main

import "fmt"

type Foo struct {
  x int
}

func (f Foo) foo1() {
  fmt.Println("foo1")
  f.x = 1
}

func (f *Foo) foo2() {
  fmt.Println("foo2")
  f.x = 2
}

type InterfaceFoo1 interface {
  foo1()
}

type InterfaceFoo2 interface {
  foo2()
}

func useFoo1(m InterfaceFoo1) {
  fmt.Printf("the type is: %T\n", m)
  m.foo1()
}

func useFoo2(m InterfaceFoo2) {
  fmt.Printf("the type2 is: %T\n", m)
  m.foo2()
}

func useFoo3(m *InterfaceFoo2) {
  fmt.Printf("the type3 is: %T\n", m)
  (*m).foo2()  // must be (*m), can't be m.foo2()
}

func f1(f Foo) {
  fmt.Println(f.x)
}

func f2(f *Foo) {
  fmt.Println(f.x)
}

func main() {
  fmt.Println("Hello, playground")
  z:=Foo{x:3}
  f1(z)

 // f2(z)

  y:=&Foo{x:4}
  f2(y)     
 // f1(y)

  useFoo1(z)    
  fmt.Printf("z.x: %d\n", z.x)

  useFoo2(y)
  fmt.Printf("y.x: %d\n", y.x)

  y=&Foo{x:7}     
  fmt.Printf("y.x: %d\n", y.x)

  useFoo1(y)    
  fmt.Printf("y.x: %d\n", y.x)

//  useFoo2(z)    

  var ip1 InterfaceFoo1 = z 
  useFoo1(ip1)

  var ip11 InterfaceFoo1 = y 
  useFoo1(ip11)

  var ip2 InterfaceFoo2 = y      
  useFoo2(ip2)        

  var ip22 InterfaceFoo2 = &z      
  useFoo2(ip22)

  useFoo3(&ip22)                
}

Hello, playground
3
4
the type is: main.Foo
foo1
z.x: 3
the type2 is: *main.Foo
foo2
y.x: 2
y.x: 7
the type is: *main.Foo
foo1
y.x: 7
the type is: main.Foo
foo1
the type is: *main.Foo
foo1
the type2 is: *main.Foo
foo2
the type2 is: *main.Foo
foo2
the type3 is: *main.InterfaceFoo2
foo2

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License