-
Hi I'm having trouble using reflection to set values in a struct. Extracting data was straightforward, but setting it using reflected data seems trickier I was under the impression struct_field_by_name was providing a pointer, but when I set the value, it doesn't set it in the struct
Does it just copy the value? Should I be using the offset in Struct_Field instead? (or struct_field_offsets) Update: I'm currently setting values like so
I obviously cut out most of my code, but is there a more concise way of doing this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Hi, yes. You were very close. package main
import "core:fmt"
import "core:reflect"
main :: proc() {
Foo :: struct {
a: int, b: int,
}
my_struct := Foo{a = 1, b = 2}
f := reflect.struct_field_value_by_name(my_struct, "b")
(^int)(f.data)^ = 6
fmt.println(f) // prints '6'
fmt.println(my_struct.b) // prints '6'
} Note that we're passing Similarly, the procedure itself returns an What we do here is poke into the |
Beta Was this translation helpful? Give feedback.
-
package main
import "core:fmt"
import "core:reflect"
Foo :: struct {
a: int,
b: ^int,
}
main :: proc() {
val_in_main := 2
my_struct := Foo{a = 1, b = &val_in_main} // 'b' points to 'val_in_main'
assign(&my_struct)
fmt.println("my_struct.a:", my_struct.a) // Expected: 6
fmt.println("my_struct.b (address):", my_struct.b) // Expected: address of val_in_main
fmt.println("Value pointed to by b (*my_struct.b):", my_struct.b^) // Expected: 6
fmt.println("Original val_in_main:", val_in_main) // Expected: 6
}
assign :: proc(dest: ^$T) {
f_a := reflect.struct_field_value_by_name(dest^, "a")
// f_a.data is a rawptr to my_struct.a (effectively ^int)
new_val_for_a := 6
(^int)(f_a.data)^ = new_val_for_a
fmt.printf("Reflected value of 'a' after modification: %d\n", f_a)
f_b := reflect.struct_field_value_by_name(dest^, "b")
// f_b.data is a rawptr to my_struct.b.
// Since my_struct.b is of type ^int, f_b.data is effectively ^(^int).
// Get the pointer value stored in field 'b'.
pointer_stored_in_b := (^(^int))(f_b.data)^
// Dereference ^int pointer to assign to the integer it points to.
new_val_for_target_of_b := 6
pointer_stored_in_b^ = new_val_for_target_of_b
fmt.printf("Address: %v and Value: %d pointed to by field 'b'\n", pointer_stored_in_b, pointer_stored_in_b^)
} |
Beta Was this translation helpful? Give feedback.
Hi, yes. You were very close.
Note that we're passing
my_struct
, not&my_struct
, tostruct_field_value_by_name
. Theany
parameter automatically takes the address of the thing you pass into it. So now we're passing a typeFoo
instead of type^Foo
.Similarly, the procedure itself returns an
any
, which can have any value and type assigned to it. When you performed the direct assignment of 6, …