有两种 option ,一种是用 func ,一种是用 interface

可以用于New 对象、过滤对象。且看下面案例

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
type User struct {
Name string
Age int
}

type UserOption func(*User)

func NewUser(options ...UserOption) *User {
u := &User{}
for _, option := range options {
option(u)
}
return u
}

func WithName(name string) UserOption {
return func(u *User) {
u.Name = name
}
}

func WithAge(age int) UserOption {
return func(u *User) {
u.Age = age
}
}

type QueryOption interface {
ApplyTo(users []*User) []*User
}

func FindUser(users []*User, options ...QueryOption) []*User {
for _, option := range options {
users = option.ApplyTo(users)
}
return users
}

type Where struct {
Name string
Age int
}

func (w *Where) ApplyTo(users []*User) []*User {
res := make([]*User, 0, len(users))
for _, u := range users {
if u.Name == w.Name && u.Age == w.Age {
res = append(res, u)
}
}
return res
}

type Range struct {
Offset int
Limit int
}

func (r *Range) ApplyTo(users []*User) []*User {
res := make([]*User, 0, len(users))
for i := r.Offset; i < len(users) && i < r.Offset+r.Limit; i++ {
res = append(res, users[i])
}
return res
}

func TestFindUser(t *testing.T) {
u1 := NewUser(WithName("a"), WithAge(18))
u2 := NewUser(WithName("b"), WithAge(28))
u3 := NewUser(WithName("c"), WithAge(18))
u4 := NewUser(WithName("d"), WithAge(38))

users := FindUser([]*User{u1, u2, u3, u4}, &Where{Name: "a", Age: 38}, &Range{Offset: 0, Limit: 2})
fmt.Printf("%#v", users)
}