目标
使用 flag.Value 让命令行定义新的符号
原理
在 flag 包中有一个 Value 接口。实现了这个接口的类,在 flag.Parse 中调用时,会放弃默认的方式,把命令行的字符串 s 截取到自定义方法中。
![0b985c1040ff829c23e154b837535729.png](https://img-blog.csdnimg.cn/img_convert/0b985c1040ff829c23e154b837535729.png)
代码
代码结构分为 2 部分:
- 主程序
- 自定义模块
主程序
package mainimport ("flag""fmt""testBookCase/testFlag/tempconv")// 准备自定义的类var temp = tempconv.CelsiusFlag("temp", 20.0, "the temperature")// 主程序中调用func main() {flag.Parse()fmt.Println(*temp)}
自定义模块
package tempconvimport ("flag""fmt")type Celsius float64type Fahrenheit float64func FToC(f Fahrenheit) Celsius {return Celsius((f - 32) * 5/9)}func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }type celsiusFlag struct {Celsius}func (f *celsiusFlag) Set(s string) error {var unit stringvar value float64fmt.Sscanf(s, "%f%s", &value, &unit) // 从输入 s 中解析出浮点和字符串,分别赋值给 value, unitswitch unit {case "C", "°C":f.Celsius = Celsius(value)return nilcase "F", "°F":f.Celsius = FToC(Fahrenheit(value))return nil}return fmt.Errorf("invalid temperature %q", s)}func CelsiusFlag(name string, value Celsius, usage string) *Celsius {f := celsiusFlag{value}flag.CommandLine.Var(&f, name, usage)return &f.Celsius}
![9c8a911d69f5eafb34848db886460a0c.png](https://img-blog.csdnimg.cn/img_convert/9c8a911d69f5eafb34848db886460a0c.png)