Korzystając z pakietu reflect
: jaka jest różnica między korzystaniem z reflect.ValueOf().Interface()
i zapisywaniem tego do zmiennej typu interface{}
a zapisaniem do zmiennej typu interface
z pominięciem wywołania .Interface()
? Jeżeli dobrze rozumiem, to interfejsy to są wrappery na typy/structury/zmienne - jeżeli zapiszemy coś do interfejsu, to żeby potem z tego wyciągnąć value można to zrobić na dwa sposoby: albo assercją (.(int)
) albo reflect.ValueOf
- pierwsze zwróci inta, drugie reflect.Value które będzie gdzieś pod spodem jako unsafe.Pointer
trzymać adres do tego inta. W poniższym przykładzie:
intReflected := reflect.ValueOf(interface{}(10))
fmt.Printf("Type: %T, Value: %v\n", intReflected, intReflected) // reflect.Value, 10
intAsserted := interface{}(10).(int)
fmt.Printf("Type: %T, Value: %v\n", intAsserted, intAsserted) // int, 10
dynamicStruct := reflect.StructOf([]reflect.StructField{
{
Name: "Id",
Type: reflect.TypeOf(0),
},
{
Name: "Name",
Type: reflect.TypeOf(""),
},
})
instance := reflect.New(dynamicStruct)
instanceInterfacedByMethod := instance.Interface()
reflect.ValueOf(instanceInterfacedByMethod).
Elem().
FieldByName("Id").
Set(reflect.ValueOf(interface{}(10)))
var instanceInterfacedByVarType interface{} = instance
(instanceInterfacedByVarType.(reflect.Value)).
Elem().
FieldByName("Id").
Set(reflect.ValueOf(interface{}(10))) // it works
reflect.ValueOf(instanceInterfacedByVarType).
//Elem(). panic: call of reflect.Value.Elem on struct Value
FieldByName("Id"). // Type: <invalid reflect.Value>
Set(reflect.ValueOf(interface{}(10))) // panic: call of reflect.Value.Set on zero Value
Pierwsza assercja i refleksja - jak najbardziej rozumiem. Ale czemu w przypadku gdy korzystam z assercji na reflect.Value
to wszystko działa, ale jak już korzystam z reflect.ValueOf
to działa (a raczej nie działa) to kompletnie inaczej? Panici są umieszczone w komentarzach w kodzie. I czemu FieldByName
jest invalid
?