巧妙运用golang的flag

1.发现

平时比较习惯用go的flag包,但都是简单类型,有时候处理一些复杂类型时基本就是用简单类型然后内部搞一些操作检查。看了flag源码发现其实可以自定义类型的。请看下面代码:

package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "strings"
)

func main() {
    var m MyType
    flag.Var(&m, "m", "MyType")

    var s1 SliceString
    flag.Var(&s1, "s1", "s1 use [,]")

    s2 := SliceString{Sep: "|"}
    flag.Var(&s2, "s2", "s2 use [|]")

    flag.Parse()

    fmt.Printf("%#v\n", m.Get())
    fmt.Printf("%#v\n", s1.Get())
    fmt.Printf("%#v\n", s2.Get())
}

type MyType struct {
    S string
    A string `json:"a"`
    B int    `json:"b"`
    C bool   `json:"c"`
}

func (s *MyType) Get() MyType {
    return *s
}

func (s *MyType) Set(set string) error {
    s.S = set
    return json.Unmarshal([]byte(s.S), s)
}

func (s *MyType) String() string {
    return s.S
}

type SliceString struct {
    S, Sep string
}

func (s *SliceString) Get() []string {
    sep := ","
    if s.Sep != "" {
        sep = s.Sep
    }
    return strings.Split(s.S, sep)
}

func (s *SliceString) Set(set string) error {
    s.S = set
    return nil
}

func (s *SliceString) String() string {
    return s.S
}

当执行:.app -m "{"A":"abc","B":123,"C":true}" -s1 "abc,123,def" -s2 "xyz|wer|cvb"
下面是运行结果:

main.MyType{A:"abc", B:123, C:true}
[]string{"abc", "123", "def"}
[]string{"xyz", "wer", "cvb"}

captcha