I am doing some test about unsafe.Pointer. Suppose TestFun is a common library function, so "Person" struct should not appear in this function
type Person struct {
Name string
}
func main() {
p := &Person{}
p.Name = "TestName"
TestFun(p)
}
func TestFun(val interface{}) {
// I want to convert interface{} to unsafe.Pointer
var pointer unsafe.Pointer
// This Line compile error
//pointer = unsafe.Pointer(val)
// This is ok, but "Person" appears. This function is a common function, "Person" should not appear
// pointer = unsafe.Pointer(val.(*Person))
println(pointer)
}
How could I do this ?
Instead of unsafe.Pointer(val), use unsafe.Pointer(&val). Because it accepts pointer.
package main
import (
"unsafe"
)
type Person struct {
Name string
}
func main() {
p := &Person{}
p.Name = "TestName"
TestFun(p)
}
func TestFun(val interface{}) {
// I want to convert interface{} to unsafe.Pointer
var pointer unsafe.Pointer
pointer = unsafe.Pointer(&val)
println(pointer)
u := (*interface{})(pointer)
p := (*u).(*Person)
println(p.Name)
}
Related
Had a rough time trying to set the interface value by using "reflect" package. The interface value is actually inside a struct of a struct. See my code in Go Playground
Basically, inside initProc, I want to assign dummyAFunc function to DummyA field in Box struct
package main
import (
"fmt"
"reflect"
)
type Box struct {
Name string
DummyA interface{}
}
type SmartBox struct {
Box
}
func dummyAFunc(i int) {
fmt.Println("dummyAFunc() is here!")
}
func initProc(inout interface{}) {
// Using "inout interface{}", I can take any struct that contains Box struct
// And my goal is assign dummyAFunc to dummyA in Box struct
iType:=reflect.TypeOf(inout)
iValue:=reflect.ValueOf(inout)
fmt.Println("Type & value:", iType.Elem(), iValue.Elem()) // Type & value: *main.SmartBox &{{ <nil>}}
e := reflect.ValueOf(inout).Elem()
fmt.Println("Can set?", e.CanSet()). // true
fmt.Println("NumField", e.NumField()) // panic: reflect: call of reflect.Value.NumField on ptr Value ?????
fmt.Println("NumMethod", e.NumMethod()) // NumMethod = 0
}
func main() {
smartbox := new (SmartBox)
initProc(&smartbox)
}
I'm new to Go and I've read the The laws of Reflection but still can't figure it out. Please help. Thanks!
You are passing a **SmartBix to initProc. So when you dereference once with reflect's Elem() you are still getting a pointer (*Smart box).
Since new already returns a pointer, just use:
smartbox := new (SmartBox)
// InitProc(smartbox) // **SmartBox
InitProc(smartbox) // *SmartBox
https://play.golang.org/p/j4q6aq6QL_4
EDIT
To update the input struct's DummyA field, you can do something like this:
func initProc2(v interface{}) error {
if reflect.TypeOf(v).Kind() != reflect.Ptr {
return fmt.Errorf("value must be a pointer")
}
dv := reflect.ValueOf(v).Elem()
if dv.Kind() != reflect.Struct {
return fmt.Errorf("value must be a pointer to a struct/interface")
}
const fname = "DummyA" // lookup field name
f := dv.FieldByName(fname)
if !f.CanSet() {
return fmt.Errorf("value has no field %q or cannot be set", fname)
}
nv := reflect.ValueOf(dummyAFunc)
f.Set(nv)
return nil
}
Working example: https://play.golang.org/p/VE751GtSGEw
I am making a memory pool in Go.
I am doing so because implicit converting int to interface{} will trigger a memory allocation.I want to avoid the allocation.
I want to allocate several types of pointers in one pool.
The pool is something like this.
type creator struct{
buf []interface{}
}
func (cr *creator) Create()*interface{}{
if len(cr.buf)==0{
cr.buf=make([]interface{},256)
}
current:=&cr.buf[0]
cr.buf=cr.buf[1:]
return current
}
func (cr *creator)CreateInt()*int{
pointer:=cr.Create()
return (*int)(unsafe.Pointer(pointer)) // <-- right or wrong?
}
Is the code valid?
You have *interface {} and you want to pretend that it is *int! How is that going to work?
package main
import (
"fmt"
"unsafe"
)
func main() {
var cr creator
pointer := cr.CreateInt()
fmt.Printf("%T\n", pointer) // *int
}
type creator struct {
buf []interface{}
}
func (cr *creator) Create() *interface{} {
if len(cr.buf) == 0 {
cr.buf = make([]interface{}, 256)
}
current := &cr.buf[0]
cr.buf = cr.buf[1:]
return current
}
func (cr *creator) CreateInt() *int {
pointer := cr.Create()
fmt.Printf("%T\n", pointer) // *interface {}
return (*int)(unsafe.Pointer(pointer)) // *interface {} to *int
}
Playground: https://play.golang.org/p/TLF7kbYPA0M
Output:
*interface {} 0x452000
*int 0x452000
I want to use some external code that requires a pointer to a struct. At the point that the code is called, I have an interface variable.
When creating a pointer off of that variable, the pointer's type is interface{}* when I need it to be the pointer type of the struct's type.
Image the code in TestCanGetStructPointer does not know about the Cat class, and that it exists in some external package.
How can I cast it to this?
Here is a code sample:
import (
"reflect"
"testing"
)
type Cat struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{}
}
var somethingForCats = SomethingGeneric{getSomething: getSomeCat}
func TestCanGetStructPointer(t *testing.T) {
interfaceVariable := somethingForCats.getSomething()
pointer := &interfaceVariable
interfaceVarType := reflect.TypeOf(interfaceVariable)
structPointerType := reflect.PtrTo(interfaceVarType)
pointerType := reflect.TypeOf(pointer)
if pointerType != structPointerType {
t.Errorf("Pointer type was %v but expected %v", pointerType, structPointerType)
}
}
The test fails with:
Pointer type was *interface {} but expected *parameterized.Cat
#dyoo's example does work, but it relies on you to manually cast Dog and Cat.
Here's a bit of a convoluted/verbose example which avoids that constraint somewhat:
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{name: "Fuzzy Wuzzy"}
}
var somethingForCats = SomethingGeneric{getSomething: getSomeCat}
func main() {
interfaceVariable := somethingForCats.getSomething()
castVar := reflect.ValueOf(interfaceVariable)
castVar.Convert(castVar.Type())
// If you want a pointer, do this:
fmt.Println(reflect.PtrTo(castVar.Type()))
// The deref'd val
if castVar.Type() != reflect.TypeOf(Cat{}) {
fmt.Printf("Type was %v but expected %v\n", castVar, reflect.TypeOf(&Cat{}))
} else {
fmt.Println(castVar.Field(0))
}
}
Playground Link
I found this thread: https://groups.google.com/forum/#!topic/golang-nuts/KB3_Yj3Ny4c
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
fmt.Println("obj is a", reflect.TypeOf(obj).Name())
// Create a new instance of the underlying type
vp := reflect.New(reflect.TypeOf(obj))
// Should be a *Cat and Cat respectively
fmt.Println("vp is", vp.Type(), " to a ", vp.Elem().Type())
vp.Elem().Set(reflect.ValueOf(obj))
// NOTE: `vp.Elem().Set(reflect.ValueOf(&obj).Elem())` does not work
// Return a `Cat` pointer to obj -- i.e. &obj.(*Cat)
return vp.Interface()
}
//
// Dump out a pointer ...
//
func test_ptr(ptr interface{}) {
v := reflect.ValueOf(ptr)
fmt.Println("ptr is a", v.Type(), "to a", reflect.Indirect(v).Type())
}
func main() {
cat := Cat{name: "Fuzzy Wuzzy"}
// Reports "*main.Cat"
test_ptr(&cat)
// Get a "*Cat" generically via interface{}
sp := to_struct_ptr(cat)
// *should* report "*main.Cat" also
test_ptr(sp)
fmt.Println("sp is",sp)
}
The following may help: http://play.golang.org/p/XkdzeizPpP
package main
import (
"fmt"
)
type Cat struct {
name string
}
type Dog struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{name: "garfield"}
}
func getSomeDog() interface{} {
return Dog{name: "fido"}
}
var somethings = []SomethingGeneric{
SomethingGeneric{getSomething: getSomeCat},
SomethingGeneric{getSomething: getSomeDog},
}
func main() {
for _, something := range somethings {
interfaceVariable := something.getSomething()
cat, isCat := interfaceVariable.(Cat)
dog, isDog := interfaceVariable.(Dog)
fmt.Printf("cat %v %v\n", cat, isCat)
fmt.Printf("dog %v %v\n", dog, isDog)
}
}
If I have a struct like this
type myStruct struct {
mystring string
myint int
}
and if I have a function that returns a new myStruct like this
func New() myStruct {
s := myStruct{}
s.mystring = "string"
s.myint = 1
return s
}
Because I first store it in the "s" variable before returning it, is my function actually making 2 myStruct values instead of one?
And if so, is it then a better practice to make sure I don't first store it in the variable?
The return statement will return a copy of the myStruct object value. If it is a small object then this is fine.
If you intend for the caller to be able to modify this object, and the struct will have methods that use a pointer as the receiver, then it makes more sense to return a pointer to your struct instead:
func New() *myStruct {
s := myStruct{}
s.mystring = "string"
s.myint = 1
return &s
}
You can see the copy happening when you compare the memory address of value vs pointer return types: http://play.golang.org/p/sj6mivYSHg
package main
import (
"fmt"
)
type myStruct struct {
mystring string
myint int
}
func NewObj() myStruct {
s := myStruct{}
fmt.Printf("%p\n", &s)
return s
}
func NewPtr() *myStruct {
s := &myStruct{}
fmt.Printf("%p\n",s)
return s
}
func main() {
o := NewObj()
fmt.Printf("%p\n",&o)
p := NewPtr()
fmt.Printf("%p\n",p)
}
0xf8400235a0 // obj inside NewObj()
0xf840023580 // obj returned to caller
0xf840023640 // ptr inside of NewPtr()
0xf840023640 // ptr returned to caller
I'm definitely not a Go expert (or even novice :) ), but as #max.haredoom mentioned, you can allocate variables in the function signature itself. In that way, you can also omit the s in the return:
package main
import "fmt"
type myStruct struct {
mystring string
myint int
}
func New() (s myStruct) {
s.mystring = "string"
s.myint = 1
return
}
func main() {
r := New()
fmt.Println(r)
}
// Outputs {string 1}
In the examples that I have come across in Effective Go, it does seem to be the most common way of doing things of this nature, but again, I am definitely not an authority on the subject (and will look for additional info on the actual performance).
I think I found the answer by using defer.
I updated the function so that there's a deferred modification to the myStruct value. This means it will happen after the return, but before it is received on the other end.
When I do this, the struct that is received by the caller does not show the updated value, so it appears as though I am indeed returning a copy.
func New() myStruct {
s := myStruct{}
defer func() {
s.mystring = "new value" // defer an update to the value
}()
s.mystring = "string"
s.myint = 1
return s
}
func main() {
b := New()
fmt.Println(b) // still shows the original value
}
http://play.golang.org/p/WWQi8HpDny
In Go, how do you create the instance of an object from its type at run time? I suppose you would also need to get the actual type of the object first too?
I am trying to do lazy instantiation to save memory.
In order to do that you need reflect.
package main
import (
"fmt"
"reflect"
)
func main() {
// one way is to have a value of the type you want already
a := 1
// reflect.New works kind of like the built-in function new
// We'll get a reflected pointer to a new int value
intPtr := reflect.New(reflect.TypeOf(a))
// Just to prove it
b := intPtr.Elem().Interface().(int)
// Prints 0
fmt.Println(b)
// We can also use reflect.New without having a value of the type
var nilInt *int
intType := reflect.TypeOf(nilInt).Elem()
intPtr2 := reflect.New(intType)
// Same as above
c := intPtr2.Elem().Interface().(int)
// Prints 0 again
fmt.Println(c)
}
You can do the same thing with a struct type instead of an int. Or anything else, really. Just be sure to know the distinction between new and make when it comes to map and slice types.
As reflect.New doesn't automatically make reference types used in struct fields, you could use something like the following to recursively initialize those field types (note the recursive struct definition in this example):
package main
import (
"fmt"
"reflect"
)
type Config struct {
Name string
Meta struct {
Desc string
Properties map[string]string
Users []string
}
}
func initializeStruct(t reflect.Type, v reflect.Value) {
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
ft := t.Field(i)
switch ft.Type.Kind() {
case reflect.Map:
f.Set(reflect.MakeMap(ft.Type))
case reflect.Slice:
f.Set(reflect.MakeSlice(ft.Type, 0, 0))
case reflect.Chan:
f.Set(reflect.MakeChan(ft.Type, 0))
case reflect.Struct:
initializeStruct(ft.Type, f)
case reflect.Ptr:
fv := reflect.New(ft.Type.Elem())
initializeStruct(ft.Type.Elem(), fv.Elem())
f.Set(fv)
default:
}
}
}
func main() {
t := reflect.TypeOf(Config{})
v := reflect.New(t)
initializeStruct(t, v.Elem())
c := v.Interface().(*Config)
c.Meta.Properties["color"] = "red" // map was already made!
c.Meta.Users = append(c.Meta.Users, "srid") // so was the slice.
fmt.Println(v.Interface())
}
You can use reflect.Zero() which will return the representation of the zero value of the struct type. (similar to if you did var foo StructType) This is different from reflect.New() as the latter will dynamically allocate the struct and give you a pointer, similar to new(StructType)
Here's a basic example like Evan Shaw gave, but with a struct:
package main
import (
"fmt"
"reflect"
)
func main() {
type Product struct {
Name string
Price string
}
var product Product
productType := reflect.TypeOf(product) // this type of this variable is reflect.Type
productPointer := reflect.New(productType) // this type of this variable is reflect.Value.
productValue := productPointer.Elem() // this type of this variable is reflect.Value.
productInterface := productValue.Interface() // this type of this variable is interface{}
product2 := productInterface.(Product) // this type of this variable is product
product2.Name = "Toothbrush"
product2.Price = "2.50"
fmt.Println(product2.Name)
fmt.Println(product2.Price)
}
Per newacct's response, using Reflect.zero it would be:
var product Product
productType := reflect.TypeOf(product) // this type of this variable is reflect.Type
productValue := reflect.Zero(productType) // this type of this variable is reflect.Value
productInterface := productValue.Interface() // this type of this variable is interface{}
product2 := productInterface.(Product) // the type of this variable is Product
This is a great article on the basics of reflection in go.
You don't need reflect and you can do this easy with factory pattern if they share the same interface:
package main
import (
"fmt"
)
// Interface common for all classes
type MainInterface interface {
GetId() string
}
// First type of object
type FirstType struct {
Id string
}
func (ft *FirstType) GetId() string {
return ft.Id
}
// FirstType factory
func InitializeFirstType(id string) MainInterface {
return &FirstType{Id: id}
}
// Second type of object
type SecondType struct {
Id string
}
func (st *SecondType) GetId() string {
return st.Id
}
// SecondType factory
func InitializeSecondType(id string) MainInterface {
return &SecondType{Id: id}
}
func main() {
// Map of strings to factories
classes := map[string]func(string) MainInterface{
"first": InitializeFirstType,
"second": InitializeSecondType,
}
// Create a new FirstType object with value of 10 using the factory
newObject := classes["first"]("10")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject.GetId())
// Create a new SecondType object with value of 20 using the factory
newObject2 := classes["second"]("20")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject2.GetId())
}