I need an empty copy of an object in go, without knowing it's type directly. This code will succesfully return an object as a pointer to the type. However, I don't seem to be able to just get the pointer value after that.
Trying to get this right, but getting hung up on being a value type. I can make the pointer thing work for my situation, but want to understand why it seems so hard to get the value.
package watch
import "reflect"
type TestStruct struct {
Name string
Data string
}
func TestClone(t *testing.T) {
var obj TestStruct
obj.Name = "test case"
gotPtr := cloneEmptyObject(obj)
got := *gotPtr.(*TestStruct)
print(got.Name)
}
// This works but returns me a pointer, and I can cast if I explicitly have the type
func cloneEmptyObject(obj interface{}) interface{} {
vesselObjPtr := reflect.New(reflect.TypeOf(obj)).Interface()
// want to do the equivalent of this without explicitly having type TestStruct:
// return *vesselObjPtr.(*TestStruct)
return vesselObjPtr
}
func TestClone2(t *testing.T) {
var obj TestStruct
obj.Name = "test case"
got := cloneEmptyObject2(obj)
b:= got.(TestStruct) //This fails and causes a panic
print(b.Name)
}
//want this where I don't explicitly need the Type to get the value
func cloneEmptyObject2(obj interface{}) interface{} {
vesselObjPtr := reflect.New(reflect.TypeOf(obj))
// return *vesselObjPtr //invalid indirect of vesselObjPtr (type "reflect".Value)
vesselObj := reflect.Indirect(vesselObjPtr)
return vesselObj // want this to be TestStruct, but it is a reflect.Value, and can't be cast
}
func TestClone3(t *testing.T) {
var obj TestStruct
obj.Name = "test case"
got := cloneEmptyObject3(obj)
b:= got.(TestStruct)
print(b.Name)
}
func cloneEmptyObject3(obj interface{}) interface{} {
return reflect.Zero(reflect.TypeOf(obj))
}
func TestClone4(t *testing.T) {
var obj TestStruct
obj.Name = "test case"
got := cloneEmptyObject4(obj)
b:= got.(TestStruct)
print(b.Name)
}
func cloneEmptyObject4(obj interface{}) interface{} {
return reflect.New(reflect.TypeOf(obj)).Elem()
}
=== RUN TestClone
--- PASS: TestClone (0.00s)
=== RUN TestClone2
--- FAIL: TestClone2 (0.00s)
panic: interface conversion: interface {} is reflect.Value, not watch.TestStruct [recovered]
panic: interface conversion: interface {} is reflect.Value, not watch.TestStruct
=== RUN TestClone3
--- FAIL: TestClone3 (0.00s)
panic: interface conversion: interface {} is reflect.Value, not watch.TestStruct [recovered]
=== RUN TestClone4
--- FAIL: TestClone4 (0.00s)
panic: interface conversion: interface {} is reflect.Value, not watch.TestStruct [recovered]
panic: interface conversion: interface {} is reflect.Value, not watch.TestStruct
Aucun commentaire:
Enregistrer un commentaire