Skip to content

Instantly share code, notes, and snippets.

@martende
Created September 29, 2022 17:49
Show Gist options
  • Save martende/d5f502dac63000450dd093cc7aa21d86 to your computer and use it in GitHub Desktop.
Save martende/d5f502dac63000450dd093cc7aa21d86 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math/rand"
"reflect"
"time"
"unsafe"
)
type I1 interface {
I1()
}
type I2 interface {
I1()
I2()
}
type I3 interface {
I1()
I3()
}
type si2 struct {
}
func (s si2) I1() {
//TODO implement me
panic("implement me")
}
func (s si2) I2() {
//TODO implement me
panic("implement me")
}
type si3 struct {
}
func (s si3) I1() {
//TODO implement me
panic("implement me")
}
func (s si3) I3() {
//TODO implement me
panic("implement me")
}
func i2() I2 {
return &si2{}
}
func i3() *si3 {
return nil
}
func i33() I3 {
return nil
}
func m(a int) I1 {
switch a {
case 0:
return i2()
case 1:
return i3()
case 2:
return i33()
}
return i2()
}
type iface struct {
typ int
ptr int
}
func main() {
rand.Seed(time.Now().Unix())
x := m(0)
fmt.Println(x == nil)
switch x.(type) {
case I2:
fmt.Println("I2", x)
case I3:
fmt.Println("I3", x)
case I1:
fmt.Println("I1", x)
default:
fmt.Println("NO")
}
x2 := m(1)
fmt.Println(x2 == nil)
switch x2.(type) {
case I2:
fmt.Println("I2", x2)
case I3:
fmt.Println("I3", x2)
hack := (*iface)(unsafe.Pointer(&x2))
fmt.Printf("PTR %08x\n", hack.ptr)
fmt.Printf("TYPE %08x\n", hack.typ)
case I1:
fmt.Println("I1", x2)
default:
fmt.Println("NO", reflect.TypeOf(x2))
}
x2 = m(2)
fmt.Println(x2 == nil)
switch x2.(type) {
case I2:
fmt.Println("I2", x2)
case I3:
fmt.Println("I3", x2)
hack := (*iface)(unsafe.Pointer(&x2))
fmt.Printf("PTR %08x\n", hack.ptr)
fmt.Printf("TYPE %08x\n", hack.typ)
case I1:
fmt.Println("I1", x2)
default:
fmt.Println("NO", reflect.TypeOf(x2))
}
}
false
I2 &{}
false
I3 <nil>
PTR 00000000
TYPE 004bb5f8
true
NO <nil>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment