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?