-
Notifications
You must be signed in to change notification settings - Fork 4
/
prepared_mapping_examples_test.go
107 lines (81 loc) · 2.23 KB
/
prepared_mapping_examples_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package set_test
import (
"fmt"
"reflect"
"github.com/nofeaturesonlybugs/set"
)
func ExamplePreparedMapping_Rebind() {
// Once a PreparedMapping has been created you can swap out the value it mutates
// by calling Rebind. This yields better performance in tight loops where
// you intend to mutate many instances of the same type.
m := &set.Mapper{}
type S struct {
Str string
Num int
}
values := [][]interface{}{
{"First", 1},
{"Second", 2},
{"Third", 3},
}
slice := make([]S, 3)
p, _ := m.Prepare(&slice[0]) // We can prepare on the first value to get a PreparedMapping
// We must call Plan with our intended field access order.
_ = p.Plan("Str", "Num")
for k := range slice {
p.Rebind(&slice[k]) // The PreparedMapping now affects slice[k]
for _, value := range values[k] {
_ = p.Set(value) // error ignored for brevity
}
}
fmt.Println(slice[0].Num, slice[0].Str)
fmt.Println(slice[1].Num, slice[1].Str)
fmt.Println(slice[2].Num, slice[2].Str)
// Output: 1 First
// 2 Second
// 3 Third
}
func ExamplePreparedMapping_Rebind_panic() {
// PreparedMapping.Rebind panics if the new instance is not the same type.
m := &set.Mapper{}
type S struct {
Str string
}
type Different struct {
Str string
}
defer func() {
if r := recover(); r != nil {
fmt.Println(r)
}
}()
var s S
var d Different
p, _ := m.Prepare(&s)
p.Rebind(&d)
// Output: mismatching types during Rebind; have *set_test.S and got *set_test.Different
}
func ExamplePreparedMapping_Rebind_reflectValue() {
// As a convenience PreparedMapping.Rebind can be called with an instance of reflect.Value
// if-and-only-if the reflect.Value is holding a type compatible with the PreparedMapping.
m := &set.Mapper{}
type S struct {
Str string
Num int
}
var s S
// Errors ignored for brevity.
p, _ := m.Prepare(&s)
_ = p.Plan("Num", "Str")
_ = p.Set(42)
_ = p.Set("Hello")
rv := reflect.New(reflect.TypeOf(s)) // reflect.New creates a *S which is the type
p.Rebind(rv) // originally bound. Therefore b.Rebind(rv) is valid.
_ = p.Set(100)
_ = p.Set("reflect.Value!")
r := rv.Elem().Interface().(S)
fmt.Println(s.Str, s.Num)
fmt.Println(r.Str, r.Num)
// Output: Hello 42
// reflect.Value! 100
}