slice_eface_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package test
  2. import (
  3. "testing"
  4. "github.com/modern-go/reflect2"
  5. "github.com/modern-go/test"
  6. "github.com/modern-go/test/must"
  7. "unsafe"
  8. "github.com/modern-go/test/should"
  9. "fmt"
  10. "context"
  11. )
  12. func Test_slice_eface(t *testing.T) {
  13. t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} {
  14. valType := api.TypeOf([]interface{}{}).(reflect2.SliceType)
  15. obj := valType.MakeSlice(5, 10)
  16. obj.([]interface{})[0] = 100
  17. obj.([]interface{})[4] = 20
  18. return obj
  19. }))
  20. t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
  21. obj := []interface{}{1, nil}
  22. valType := api.TypeOf(obj).(reflect2.SliceType)
  23. elem0 := interface{}(100)
  24. valType.SetIndex(obj, 0, &elem0)
  25. elem1 := interface{}(20)
  26. valType.SetIndex(obj, 1, &elem1)
  27. return obj
  28. }))
  29. t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
  30. obj := []interface{}{1, 2}
  31. valType := reflect2.TypeOf(obj).(reflect2.SliceType)
  32. var elem0 interface{} = 100
  33. valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0))
  34. var elem1 interface{} = 10
  35. valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1))
  36. must.Equal([]interface{}{100, 10}, obj)
  37. }))
  38. t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
  39. obj := []interface{}{1, nil}
  40. valType := api.TypeOf(obj).(reflect2.SliceType)
  41. fmt.Println(api, *valType.GetIndex(obj, 0).(*interface{}))
  42. return []interface{}{
  43. valType.GetIndex(obj, 0),
  44. valType.GetIndex(obj, 1),
  45. }
  46. }))
  47. t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
  48. obj := []interface{}{1, nil}
  49. valType := reflect2.TypeOf(obj).(reflect2.SliceType)
  50. elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0)
  51. must.Equal(1, *(*interface{})(elem0))
  52. }))
  53. t.Run("Append", testOp(func(api reflect2.API) interface{} {
  54. obj := make([]interface{}, 2, 3)
  55. obj[0] = 1
  56. obj[1] = 2
  57. valType := api.TypeOf(obj).(reflect2.SliceType)
  58. valType.Append(&obj, 3)
  59. // will trigger grow
  60. valType.Append(&obj, 4)
  61. return obj
  62. }))
  63. t.Run("UnsafeAppend", test.Case(func(ctx context.Context) {
  64. obj := make([]interface{}, 2, 3)
  65. obj[0] = 1
  66. obj[1] = 2
  67. valType := reflect2.TypeOf(obj).(reflect2.SliceType)
  68. ptr := reflect2.PtrOf(obj)
  69. var elem2 interface{} = 3
  70. valType.UnsafeAppend(ptr, unsafe.Pointer(&elem2))
  71. var elem3 interface{} = 4
  72. valType.UnsafeAppend(ptr, unsafe.Pointer(&elem3))
  73. should.Equal([]interface{}{1, 2, 3, 4}, valType.PackEFace(ptr))
  74. }))
  75. }