diff --git a/_demo/go/reflectindirect/reflect-indirect.go b/_demo/go/reflectindirect/reflect-indirect.go new file mode 100644 index 00000000..69332a47 --- /dev/null +++ b/_demo/go/reflectindirect/reflect-indirect.go @@ -0,0 +1,49 @@ +package main + +import ( + "reflect" +) + +func main() { + x := 42 + p := &x + + // Test 1: Non-pointer value - should return same value + v1 := reflect.Indirect(reflect.ValueOf(x)) + if !v1.IsValid() || v1.Interface() != 42 { + panic("Non-pointer test failed: expected 42") + } + + // Test 2: Pointer - should dereference + v2 := reflect.Indirect(reflect.ValueOf(p)) + if !v2.IsValid() || v2.Interface() != 42 { + panic("Pointer dereference test failed: expected 42") + } + + // Test 3: Nil pointer - should return invalid Value + var nilPtr *int + v3 := reflect.Indirect(reflect.ValueOf(nilPtr)) + if v3.IsValid() { + panic("Nil pointer test failed: expected invalid Value") + } + + // Test 4: Struct value - should return same value + type Person struct { + Name string + Age int + } + person := Person{Name: "Alice", Age: 30} + v4 := reflect.Indirect(reflect.ValueOf(person)) + if !v4.IsValid() || v4.Interface().(Person).Name != "Alice" || v4.Interface().(Person).Age != 30 { + panic("Struct value test failed: expected Person{Name: Alice, Age: 30}") + } + + // Test 5: Struct pointer - should dereference + personPtr := &Person{Name: "Bob", Age: 25} + v5 := reflect.Indirect(reflect.ValueOf(personPtr)) + if !v5.IsValid() || v5.Interface().(Person).Name != "Bob" || v5.Interface().(Person).Age != 25 { + panic("Struct pointer test failed: expected Person{Name: Bob, Age: 25}") + } + + println("PASS") +} diff --git a/runtime/internal/lib/reflect/value.go b/runtime/internal/lib/reflect/value.go index 4cec494d..f1657ab5 100644 --- a/runtime/internal/lib/reflect/value.go +++ b/runtime/internal/lib/reflect/value.go @@ -1759,6 +1759,16 @@ func ValueOf(i any) Value { return unpackEface(i) } +// Indirect returns the value that v points to. +// If v is a nil pointer, Indirect returns a zero Value. +// If v is not a pointer, Indirect returns v. +func Indirect(v Value) Value { + if v.Kind() != Pointer { + return v + } + return v.Elem() +} + // arrayAt returns the i-th element of p, // an array whose elements are eltSize bytes wide. // The array pointed at by p must have at least i+1 elements: