diff --git a/go.mod b/go.mod index 5527ed9..0dfc42b 100644 --- a/go.mod +++ b/go.mod @@ -6,4 +6,5 @@ require ( github.com/arl/statsviz v0.5.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect golang.org/x/net v0.2.0 // indirect + gopl.io v0.0.0-20211004154805-1ae3ec64947b // indirect ) diff --git a/go.sum b/go.sum index edf24fe..2f26eb6 100644 --- a/go.sum +++ b/go.sum @@ -2,5 +2,13 @@ github.com/arl/statsviz v0.5.1 h1:3HY0ZEB738JtguWsD1Tf1pFJZiCcWUmYRq/3OTYKaSI= github.com/arl/statsviz v0.5.1/go.mod h1:zDnjgRblGm1Dyd7J5YlbH7gM1/+HRC+SfkhZhQb5AnM= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopl.io v0.0.0-20211004154805-1ae3ec64947b h1:7X7imR4tIDID9aTy9Algx201qZnnRi1ANBum/C9fFWY= +gopl.io v0.0.0-20211004154805-1ae3ec64947b/go.mod h1:Ma727rQcq6c2t9FT4cyk3IutUQU2j0mtNkG5po6QChQ= diff --git a/src/study/day9Interface/FlagValue.go b/src/study/day9Interface/FlagValue.go new file mode 100644 index 0000000..663ef21 --- /dev/null +++ b/src/study/day9Interface/FlagValue.go @@ -0,0 +1,60 @@ +package main + +import ( + "flag" + "fmt" +) + +type Celsius float64 +type Fahrenheit float64 +type Kelvin float64 + +func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9.0/5.0 + 32.0) } +func FToC(f Fahrenheit) Celsius { return Celsius((f - 32.0) * 5.0 / 9.0) } +func KToC(k Kelvin) Celsius { return Celsius(k - 273.15) } + +// 练习7.7 为啥默认值是带有°C的字符串 +// 因为Celsius类型实现了String()方法, +// 在flag.CommandLine.Var(&f, name, usage)时, +// 会调用f.String()方法,给Flag结构体的DefValue属性就是带有°C这个符号的 +// 而default的这句话是在flag.Parse()调用其他函数中执行输出的 +// 见Flag.FlagSet.defaultUsage() 和 PrintDefaults()方法 + +func (c Celsius) String() string { return fmt.Sprintf("%gC", c) } + +// *celsiusFlag satisfies the flag.Value interface. +type celsiusFlag struct{ Celsius } + +func (f *celsiusFlag) Set(s string) error { + var unit string + var value float64 + fmt.Sscanf(s, "%f%s", &value, &unit) // no error check needed + switch unit { + case "C", "°C": + f.Celsius = Celsius(value) + return nil + case "F", "°F": + f.Celsius = FToC(Fahrenheit(value)) + return nil + case "K", "°K": + f.Celsius = KToC(Kelvin(value)) + return nil + } + return fmt.Errorf("invalid temperature %q", s) +} + +// CelsiusFlag defines a Celsius flag with the specified name, +// default value, and usage, and returns the address of the flag variable. +// The flag argument must have a quantity and a unit, e.g., "100C". +func CelsiusFlag(name string, value Celsius, usage string) *Celsius { + f := celsiusFlag{value} + flag.CommandLine.Var(&f, name, usage) + return &f.Celsius +} + +var temp = CelsiusFlag("temp", 20.0, "the temperature") + +func main() { + flag.Parse() + fmt.Println(*temp) +}