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
}