package tests import ( "github.com/modern-go/reflect2" "github.com/modern-go/test" "testing" "context" "github.com/modern-go/test/must" "github.com/modern-go/test/should" "unsafe" ) func Test_slice_eface(t *testing.T) { t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]interface{}{}).(reflect2.SliceType) obj := valType.MakeSlice(5, 10) (*obj.(*[]interface{}))[0] = 100 (*obj.(*[]interface{}))[4] = 20 return obj })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []interface{}{1, nil} valType := api.TypeOf(obj).(reflect2.SliceType) elem0 := interface{}(100) valType.SetIndex(&obj, 0, &elem0) elem1 := interface{}(20) valType.SetIndex(&obj, 1, &elem1) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := []interface{}{1, 2} valType := reflect2.TypeOf(obj).(reflect2.SliceType) var elem0 interface{} = 100 valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0)) var elem1 interface{} = 10 valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1)) must.Equal([]interface{}{100, 10}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []interface{}{1, nil} valType := api.TypeOf(obj).(reflect2.SliceType) return []interface{}{ valType.GetIndex(&obj, 0), valType.GetIndex(&obj, 1), } })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := []interface{}{1, nil} valType := reflect2.TypeOf(obj).(reflect2.SliceType) elem0 := valType.UnsafeGetIndex(unsafe.Pointer(&obj), 0) must.Equal(1, *(*interface{})(elem0)) })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]interface{}, 2, 3) obj[0] = 1 obj[1] = 2 valType := api.TypeOf(obj).(reflect2.SliceType) elem1 := interface{}(3) valType.Append(&obj, &elem1) // will trigger grow elem2 := interface{}(4) valType.Append(&obj, &elem2) return obj })) t.Run("UnsafeAppend", test.Case(func(ctx context.Context) { obj := make([]interface{}, 2, 3) obj[0] = 1 obj[1] = 2 valType := reflect2.TypeOf(obj).(reflect2.SliceType) var elem2 interface{} = 3 valType.UnsafeAppend(unsafe.Pointer(&obj), unsafe.Pointer(&elem2)) var elem3 interface{} = 4 valType.UnsafeAppend(unsafe.Pointer(&obj), unsafe.Pointer(&elem3)) should.Equal([]interface{}{1, 2, 3, 4}, valType.UnsafeIndirect(unsafe.Pointer(&obj))) })) }