goki.dev/laser@v0.1.34/ptrs_test.go (about) 1 // Copyright (c) 2023, The Goki Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package laser 6 7 import ( 8 "reflect" 9 "testing" 10 "unsafe" 11 ) 12 13 // structs are in embeds_test.go 14 15 type PtrTstSub struct { 16 Mbr1 string 17 Mbr2 int 18 } 19 20 type PtrTst struct { 21 Mbr1 string 22 Mbr2 int 23 SubField PtrTstSub 24 } 25 26 var pt = PtrTst{} 27 28 func InitPtrTst() { 29 pt.Mbr1 = "mbr1 string" 30 pt.Mbr2 = 2 31 } 32 33 func FieldValue(obj any, fld reflect.StructField) reflect.Value { 34 ov := reflect.ValueOf(obj) 35 f := unsafe.Pointer(ov.Pointer() + fld.Offset) 36 nw := reflect.NewAt(fld.Type, f) 37 return UnhideAnyValue(nw).Elem() 38 } 39 40 func SubFieldValue(obj any, fld reflect.StructField, sub reflect.StructField) reflect.Value { 41 ov := reflect.ValueOf(obj) 42 f := unsafe.Pointer(ov.Pointer() + fld.Offset + sub.Offset) 43 nw := reflect.NewAt(sub.Type, f) 44 return UnhideAnyValue(nw).Elem() 45 } 46 47 // test ability to create an addressable pointer value to fields of a struct 48 func TestNewAt(t *testing.T) { 49 InitPtrTst() 50 typ := reflect.TypeOf(pt) 51 fld, _ := typ.FieldByName("Mbr2") 52 vf := FieldValue(&pt, fld) 53 54 // fmt.Printf("Fld: %v Typ: %v vf: %v vfi: %v vfT: %v vfp: %v canaddr: %v canset: %v caninterface: %v\n", fld.Name, vf.Type().String(), vf.String(), vf.Interface(), vf.Interface(), vf.Interface(), vf.CanAddr(), vf.CanSet(), vf.CanInterface()) 55 56 vf.Elem().Set(reflect.ValueOf(int(10))) 57 58 if pt.Mbr2 != 10 { 59 t.Errorf("Mbr2 should be 10, is: %v\n", pt.Mbr2) 60 } 61 62 fld, _ = typ.FieldByName("Mbr1") 63 vf = FieldValue(&pt, fld) 64 65 // fmt.Printf("Fld: %v Typ: %v vf: %v vfi: %v vfT: %v vfp: %v canaddr: %v canset: %v caninterface: %v\n", fld.Name, vf.Type().String(), vf.String(), vf.Interface(), vf.Interface(), vf.Interface(), vf.CanAddr(), vf.CanSet(), vf.CanInterface()) 66 67 vf.Elem().Set(reflect.ValueOf("this is a new string")) 68 69 if pt.Mbr1 != "this is a new string" { 70 t.Errorf("Mbr1 should be 'this is a new string': %v\n", pt.Mbr1) 71 } 72 }