7.4 flag.Value接口
在本章,我们会学到另一个标准的接口类型flag.Value是怎么帮助命令行标记定义新的符号的。
代码
- 章节中样例
- 练习 7.6: 对tempFlag加入支持开尔文温度
- 练习 7.7: 解释为什么帮助信息在它的默认值是20.0没有包含°C的情况下输出了°C
func main() {
//7.4 flag.Value接口
test_flag()
}
//7.4 flag.Value接口
func test_flag() {
//var period = flag.Duration("period", 1*time.Second, "sleep period")
var period = flag.Duration("period", 50 * time.Millisecond, "sleep period")
//var period = flag.Duration("period", 2 * time.Minute + 30 *time.Second, "sleep period")
//var period = flag.Duration("period", 1 * time.Hour + 30 * time.Minute, "sleep period")
//var period = flag.Duration("period", 24 * time.Hour, "sleep period")
flag.Parse()
fmt.Printf("Sleeping for %v...\n", *period)
time.Sleep(*period)
type Value interface {
String() string
Set(string) error
}
fmt.Println("================================")
//var temp = tempconv.CelsiusFlag("temp", 20.0, "the temperature")
//var temp = tempconv.CelsiusFlag("temp", -18.0, "the temperature")
//flag.Parse()
//fmt.Println(*temp)
//练习 7.6: 对tempFlag加入支持开尔文温度。
var tempF = tempconv.FahrenheitFlag("temp", -18.0, "the temperature")
flag.Parse()
fmt.Println(*tempF)
//练习 7.7: 解释为什么帮助信息在它的默认值是20.0没有包含°C的情况下输出了°C。
//因为CelsiusFlag实现了set接口,一个*Celsius类型赋给了flag,flag实现的stringter接口
//最终使Celsius调用了自身实现的string方法,从而将Celsius的值转成带°C的字符串
}
tempconv.go 在原2.5章节的基础上增加的代码
//练习 7.6: 对tempFlag加入支持开尔文温度。
type fahrenheitFlag struct{ Fahrenheit }
//练习 7.6: 对tempFlag加入支持开尔文温度。
func (f *fahrenheitFlag) Set(s string) error {
var unit string
var value float64
fmt.Sscanf(s, "%f%s", &value, &unit) // no error check needed
switch unit {
case "F", "°F":
f.Fahrenheit = Fahrenheit(value)
return nil
case "C", "°C":
f.Fahrenheit = CToF(Celsius(value))
return nil
}
return fmt.Errorf("invalid temperature %q", s)
}
//练习 7.6: 对tempFlag加入支持开尔文温度。
func FahrenheitFlag(name string, value Fahrenheit, usage string) *Fahrenheit {
f := fahrenheitFlag{value}
flag.CommandLine.Var(&f, name, usage)
return &f.Fahrenheit
}