只加载一次 初始化一个配置 redis mq mysql
type Singleton struct {
}
var singleInstance *Singleton
var once sync.Once
func GetSingleTonObj() *Singleton {
once.Do(func() {
singleInstance = new(Singleton)
})
return singleInstance
}
func TestGetSingleton(t *testing.T) {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
sob := GetSingleTonObj()
fmt.Printf("%x\n", unsafe.Pointer(sob))
wg.Done()
}()
}
wg.Wait()
}
代码覆盖率
go test -v -cover
安装xxxx
go get -u github.com/xx/xxx/xx
got get -u github.com/smartystreets/goconvey/convey
启动WEH UI
/bin/govonvey
func BenchmarkConsStringByBytesBuffer(b *testing.B) {
elems := []string{"1", "2", "3", "4", "5"}
b.ResetTimer()
for i := 0; i < b.N; i++ {
var buf bytes.Buffer
for _, elem := range elems {
buf.WriteString(elem)
}
}
b.StopTimer()
}
反射:
func CheckType(v interface{}) {
t := reflect.TypeOf(v)
switch t.Kind() {
case reflect.Float64, reflect.Float32:
fmt.Println("float")
case reflect.Int64:
fmt.Println(":long")
}
}
type Employee struct {
EmployeeID string
Name string `format:"normal"`
Age int
}
func (e *Employee) UpdateAge(newVal int) {
e.Age = newVal
}
//按名称访问结构的成员
//reflect.ValueOf(*e).FieldByName("name")
//按名字访问结构的方法
//reflect.ValueOf(e).MethodByName("updateAge").Call([]reflect.Value{reflect.ValueOf(1)})
func TestReflect(t *testing.T) {
e := &Employee{"1", "Mike", 30}
if nameField, ok := reflect.TypeOf(*e).FieldByName("Name"); !ok {
t.Errorf("Failed to get 'Name' field")
} else {
t.Log("Tag:format", nameField.Tag.Get("format"))
}
reflect.ValueOf(e).MethodByName("UpdateAge").Call([]reflect.Value{reflect.ValueOf(1)})
t.Log("Updated Age:", e)
}
通过反射 根据字段名称和字段类型判断 给对象赋值
func fillBySetting(st interface{}, setting map[string]interface{}) interface{} {
if setting == nil {
return errors.New("setting is nil.")
}
if reflect.TypeOf(st).Kind() != reflect.Ptr {
if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {
return errors.New("this first param should be a pointer to the struct type")
}
}
var (
tempField reflect.StructField
ok1 bool
)
for k, v := range setting {
if tempField, ok1 = reflect.ValueOf(st).Elem().Type().FieldByName(k); !ok1 {
continue
}
if tempField.Type == reflect.TypeOf(v) {
vstr := reflect.ValueOf(st)
vstr = vstr.Elem()
vstr.FieldByName(k).Set(reflect.ValueOf(v))
}
}
return nil
}
func TestFillNameAndAge(t *testing.T) {
setting := map[string]interface{}{"Name": "MIke", "Age": 5}
e := Employee{}
if err := fillBySetting(&e, setting); err != nil {
t.Fatal(err)
}
c := new(Customer)
if err := fillBySetting(c, setting); err != nil {
t.Fatal(err)
}
}
https://github.com/geektime-geekbang/go_learning/tree/master/code/ch41/microkernel
easyjson
https://github.com/geektime-geekbang/go_learning/tree/master/code