mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-17 11:14:20 +08:00
回到简体
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## 7.4. flag.Value接口
|
||||
|
||||
在本章,我們會學到另一個標準的接口類型flag.Value是怎麽幫助命令行標記定義新的符號的。思考下面這個會休眠特定時間的程序:
|
||||
在本章,我们会学到另一个标准的接口类型flag.Value是怎么帮助命令行标记定义新的符号的。思考下面这个会休眠特定时间的程序:
|
||||
|
||||
<u></i>gopl.io/ch7/sleep</i></u>
|
||||
```go
|
||||
@@ -14,7 +14,7 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
在它休眠前它會打印出休眠的時間週期。fmt包調用time.Duration的String方法打印這個時間週期是以用戶友好的註解方式,而不是一個納秒數字:
|
||||
在它休眠前它会打印出休眠的时间周期。fmt包调用time.Duration的String方法打印这个时间周期是以用户友好的注解方式,而不是一个纳秒数字:
|
||||
|
||||
```
|
||||
$ go build gopl.io/ch7/sleep
|
||||
@@ -22,7 +22,7 @@ $ ./sleep
|
||||
Sleeping for 1s...
|
||||
```
|
||||
|
||||
默認情況下,休眠週期是一秒,但是可以通過 -period 這個命令行標記來控製。flag.Duration函數創建一個time.Duration類型的標記變量併且允許用戶通過多種用戶友好的方式來設置這個變量的大小,這種方式還包括和String方法相同的符號排版形式。這種對稱設計使得用戶交互良好。
|
||||
默认情况下,休眠周期是一秒,但是可以通过 -period 这个命令行标记来控制。flag.Duration函数创建一个time.Duration类型的标记变量并且允许用户通过多种用户友好的方式来设置这个变量的大小,这种方式还包括和String方法相同的符号排版形式。这种对称设计使得用户交互良好。
|
||||
|
||||
```
|
||||
$ ./sleep -period 50ms
|
||||
@@ -35,7 +35,7 @@ $ ./sleep -period "1 day"
|
||||
invalid value "1 day" for flag -period: time: invalid duration 1 day
|
||||
```
|
||||
|
||||
因爲時間週期標記值非常的有用,所以這個特性被構建到了flag包中;但是我們爲我們自己的數據類型定義新的標記符號是簡單容易的。我們隻需要定義一個實現flag.Value接口的類型,如下:
|
||||
因为时间周期标记值非常的有用,所以这个特性被构建到了flag包中;但是我们为我们自己的数据类型定义新的标记符号是简单容易的。我们只需要定义一个实现flag.Value接口的类型,如下:
|
||||
|
||||
```go
|
||||
package flag
|
||||
@@ -47,9 +47,9 @@ type Value interface {
|
||||
}
|
||||
```
|
||||
|
||||
String方法格式化標記的值用在命令行幫組消息中;這樣每一個flag.Value也是一個fmt.Stringer。Set方法解析它的字符串參數併且更新標記變量的值。實際上,Set方法和String是兩個相反的操作,所以最好的辦法就是對他們使用相同的註解方式。
|
||||
String方法格式化标记的值用在命令行帮组消息中;这样每一个flag.Value也是一个fmt.Stringer。Set方法解析它的字符串参数并且更新标记变量的值。实际上,Set方法和String是两个相反的操作,所以最好的办法就是对他们使用相同的注解方式。
|
||||
|
||||
讓我們定義一個允許通過攝氏度或者華氏溫度變換的形式指定溫度的celsiusFlag類型。註意celsiusFlag內嵌了一個Celsius類型(§2.5),因此不用實現本身就已經有String方法了。爲了實現flag.Value,我們隻需要定義Set方法:
|
||||
让我们定义一个允许通过摄氏度或者华氏温度变换的形式指定温度的celsiusFlag类型。注意celsiusFlag内嵌了一个Celsius类型(§2.5),因此不用实现本身就已经有String方法了。为了实现flag.Value,我们只需要定义Set方法:
|
||||
|
||||
<u><i>gopl.io/ch7/tempconv</i></u>
|
||||
```go
|
||||
@@ -72,9 +72,9 @@ func (f *celsiusFlag) Set(s string) error {
|
||||
}
|
||||
```
|
||||
|
||||
調用fmt.Sscanf函數從輸入s中解析一個浮點數(value)和一個字符串(unit)。雖然通常必須檢査Sscanf的錯誤返迴,但是在這個例子中我們不需要因爲如果有錯誤發生,就沒有switch case會匹配到。
|
||||
调用fmt.Sscanf函数从输入s中解析一个浮点数(value)和一个字符串(unit)。虽然通常必须检查Sscanf的错误返回,但是在这个例子中我们不需要因为如果有错误发生,就没有switch case会匹配到。
|
||||
|
||||
下面的CelsiusFlag函數將所有邏輯都封裝在一起。它返迴一個內嵌在celsiusFlag變量f中的Celsius指針給調用者。Celsius字段是一個會通過Set方法在標記處理的過程中更新的變量。調用Var方法將標記加入應用的命令行標記集合中,有異常複雜命令行接口的全局變量flag.CommandLine.Programs可能有幾個這個類型的變量。調用Var方法將一個*celsiusFlag參數賦值給一個flag.Value參數,導致編譯器去檢査*celsiusFlag是否有必須的方法。
|
||||
下面的CelsiusFlag函数将所有逻辑都封装在一起。它返回一个内嵌在celsiusFlag变量f中的Celsius指针给调用者。Celsius字段是一个会通过Set方法在标记处理的过程中更新的变量。调用Var方法将标记加入应用的命令行标记集合中,有异常复杂命令行接口的全局变量flag.CommandLine.Programs可能有几个这个类型的变量。调用Var方法将一个*celsiusFlag参数赋值给一个flag.Value参数,导致编译器去检查*celsiusFlag是否有必须的方法。
|
||||
|
||||
```go
|
||||
// CelsiusFlag defines a Celsius flag with the specified name,
|
||||
@@ -87,7 +87,7 @@ func CelsiusFlag(name string, value Celsius, usage string) *Celsius {
|
||||
}
|
||||
```
|
||||
|
||||
現在我們可以開始在我們的程序中使用新的標記:
|
||||
现在我们可以开始在我们的程序中使用新的标记:
|
||||
|
||||
<u><i>gopl.io/ch7/tempflag</i></u>
|
||||
```go
|
||||
@@ -99,7 +99,7 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
下面是典型的場景:
|
||||
下面是典型的场景:
|
||||
|
||||
```
|
||||
$ go build gopl.io/ch7/tempflag
|
||||
@@ -120,6 +120,6 @@ Usage of ./tempflag:
|
||||
the temperature (default 20°C)
|
||||
```
|
||||
|
||||
**練習 7.6:** 對tempFlag加入支持開爾文溫度。
|
||||
**练习 7.6:** 对tempFlag加入支持开尔文温度。
|
||||
|
||||
**練習 7.7:** 解釋爲什麽幫助信息在它的默認值是20.0沒有包含°C的情況下輸出了°C。
|
||||
**练习 7.7:** 解释为什么帮助信息在它的默认值是20.0没有包含°C的情况下输出了°C。
|
||||
|
||||
Reference in New Issue
Block a user