-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathvar.go
96 lines (82 loc) · 2.01 KB
/
var.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
package gisp
import (
"reflect"
)
// Var 定义了变量的结构
type Var interface {
Get() interface{}
Set(interface{})
Type() reflect.Type
}
// OptionVar 定义了可空变量
type OptionVar struct {
slot reflect.Value
}
// Get 提供变量值或者 nul
func (optVar OptionVar) Get() interface{} {
if optVar.slot.Elem().IsNil() {
return nil
}
return reflect.Indirect(optVar.slot).Elem().Interface()
}
// Set 实现了赋值逻辑
func (optVar *OptionVar) Set(value interface{}) {
if value == nil {
null := reflect.Zero(reflect.PtrTo(optVar.Type()))
optVar.slot.Elem().Set(null)
return
}
val := reflect.New(optVar.Type())
val.Elem().Set(reflect.ValueOf(value))
reflect.Indirect(optVar.slot).Set(val)
}
// Type 实现了类型访问
func (optVar OptionVar) Type() reflect.Type {
return optVar.slot.Type().Elem().Elem()
}
// DefOption 构造一个可空的变量
func DefOption(typ reflect.Type) OptionVar {
slot := reflect.New(reflect.PtrTo(typ))
null := reflect.Zero(reflect.PtrTo(typ))
slot.Elem().Set(null)
return OptionVar{slot}
}
// StrictVar 定了非 Option 的变量,它简单的封装了 reflect.Value
type StrictVar struct {
slot reflect.Value
}
// Get 提供了变量值
func (svar StrictVar) Get() interface{} {
if svar.slot.IsNil() {
return nil
}
return svar.slot.Elem().Interface()
}
// Set 实现了赋值行为
func (svar *StrictVar) Set(value interface{}) {
svar.slot.Elem().Set(reflect.ValueOf(value))
}
// Type 给出变量给类型
func (svar StrictVar) Type() reflect.Type {
return svar.slot.Type().Elem()
}
// DefStrict 构造 Strict 变量
func DefStrict(typ reflect.Type) StrictVar {
slot := reflect.New(typ)
return StrictVar{slot}
}
// StrictVarAs 按照值的类型构造对应的 slot
func StrictVarAs(x interface{}) StrictVar {
slot := DefStrict(reflect.TypeOf(x))
slot.Set(x)
return slot
}
// VarSlot 构造一个指定类型的 slot
func VarSlot(typ Type) Var {
if typ.Option() {
ret := DefOption(typ.Type)
return &ret
}
ret := DefStrict(typ.Type)
return &ret
}