好久没写golang相关的blog了, 记录一些常见的golang技巧。
1. 不影响函数调用, 增加参数
先看以下函数调用:
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import "fmt"
func ExecUser(name string, age int) { fmt.Println("name:", name, "age:", age) }
func main() { ExecUser("levonfly", 9) }
|
这时候我想在原函数参数中传入我的邮箱等信息, 不仅需要修改函数定义, 还会影响以前的调用.
在不影响以前函数调用的情况下, 支持动态传参. 并且在动态的基础上加上 key
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
| package main
import "fmt"
type ArgFunc func() (key string, value string)
func BuildArgFunc(key string, value string) ArgFunc { return func() (k string, v string) { k = key v = value return } }
func ExecUser(name string, age int, funcArgs ...ArgFunc) { fmt.Println("name:", name, "age:", age) for _, funcArg := range funcArgs { k, v := funcArg() fmt.Println(k, v) } }
func main() { ExecUser("levonfly", 9) ExecUser("levonfly", 9, BuildArgFunc("email", "levonfly@gmail.com")) ExecUser("levonfly", 9, BuildArgFunc("email", "levonfly@gmail.com"), BuildArgFunc("sex", "man")) }
|
2. 临时增加struct字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import ( "encoding/json" "fmt" )
type Fixed struct { Name string `json:"name"` Age int `json:"age"` }
func main() { outputJson(Fixed{Name: "levon", Age: 9}) }
func outputJson(res interface{}) { data, _ := json.Marshal(res) fmt.Println(string(data)) }
|
Fixed假设是别人定义的结构体, 不能修改, 但是我要想让结构体增加一下当前的时间
2.1 临时struct增加字段
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
| package main
import ( "encoding/json" "fmt" "time" )
type Fixed struct { Name string `json:"name"` Age int `json:"age"` }
func main() { o := struct { Fixed Time string `json:"time"` }{ Fixed: Fixed{Name: "levon", Age: 9}, Time: time.Now().Format("2006-01-02"), } outputJson(o) }
func outputJson(res interface{}) { data, _ := json.Marshal(res) fmt.Println(string(data)) }
|
2.2 临时struct重写json
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
| package main
import ( "encoding/json" "fmt" "time" )
type Fixed struct { Name string `json:"name"` Age int `json:"age"` }
type NewFixed struct { Fixed }
func (u *NewFixed) MarshalJSON() ([]byte, error) { type Alias NewFixed return json.Marshal(&struct { *Alias Time string `json:"time"` }{ Alias: (*Alias)(u), Time: time.Now().Format("2006-01-02"), }) }
func main() { outputJson(&NewFixed{Fixed{Name: "levonfly", Age: 9}}) }
func outputJson(res interface{}) { data, _ := json.Marshal(res) fmt.Println(string(data)) }
|
3. 临时为struct增加一个动态结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "encoding/json" "fmt" )
type Info struct { A string `json:"a"` B int `json:"b"` C string `json:"c"` }
func main() { info := &Info{A: "str1", B: 100, C: "str2"} outputJson(info) }
func outputJson(res interface{}) { data, _ := json.Marshal(res) fmt.Println(string(data)) }
|
这时候加入一个动态的结构体, 例如下面有可能是1个d的结构, 也有可能是 2个属性e,f 的结构, 并把他们组合
1 2
| {"d":"123"} {"e":"123", "f":200}
|
解决思路就是倒入到一个 map[string]interface{} 里
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
| package main
import ( "encoding/json" "fmt" )
type Info struct { A string `json:"a"` B int `json:"b"` C string `json:"c"` }
func main() { info := &Info{A: "str1", B: 100, C: "str2"}
vars1 := `{"d":"123"}` vars2 := `{"e":"123", "f":200}`
outPuts := make(map[string]interface{}) respByte, _ := json.Marshal(info) _ = json.Unmarshal(respByte, &outPuts) _ = json.Unmarshal([]byte(vars1), &outPuts) _ = json.Unmarshal([]byte(vars2), &outPuts)
outputJson(outPuts) }
func outputJson(res interface{}) { data, _ := json.Marshal(res) fmt.Println(string(data)) }
|
4. struct和interface
4.1 限制一个struct实现interface
如果Engine
没有实现Engine
, 会报错.
1 2
| var _ IRouter = &Engine{} var _ IRouter = (*Engine)(nil)
|
5. 参考资料