Go--Time.Duration 没有实现Set方法

Go程序设计中 7.4 小节 flag.Value接口的代码如下

var period = flag.Duration("period", 1*time.Second, "sleep period")

func main() {
    flag.Parse()
    fmt.Printf("Sleeping for %v...", *period)
    time.Sleep(*period)
    fmt.Println()
}

运行结果

$ ./sleep -period 50ms
Sleeping for 50ms...
$ ./sleep -period 2m30s
Sleeping for 2m30s...
$ ./sleep -period 1.5h
Sleeping for 1h30m0s...
$ ./sleep -period "1 day"
invalid value "1 day" for flag -period: time: invalid duration 1 day

书中部分内容如下

因为时间周期标记值非常的有用,所以这个特性被构建到了flag包中;
但是我们为我们自己的数据类型定义新的标记符号是简单容易的。  
我们只需要定义一个实现flag.Value接口的类型,如下:
package flag

// Value is the interface to the value stored in a flag.
type Value interface {
    String() string
    Set(string) error
}

看到这之后就想到 time.Duration 应该也实现了 Value 接口,但是点进去只找到 Duration的 String方法,并没有发现Set方法, 我的疑问既然Duration没有Set方法就没有实现Vlaue这个接口,它有如何 接受像上面 xxh xxm xxs (50ms,1h...) 的参数那?Duration int64

阅读 2.2k
1 个回答

1.可以通过代码跟踪方式来查找 2.也可以在集成开发环境中查一下API

var period = flag.Duration("period", 1 * time.Second, "sleep peroid") 在这行代码执行的过程中会有经历下面类型从新定义的一个环节.

在 flag 包中有如下定义

/// 重新定义 durationValue time.Duration
type durationValue time.Duration

func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
    *p = val
    return (*durationValue)(p)
}
/// Set方法
func (d *durationValue) Set(s string) error {
    v, err := time.ParseDuration(s)
    *d = durationValue(v)
    return err
}

func (d *durationValue) Get() interface{} { return time.Duration(*d) }

/// String 方法
func (d *durationValue) String() string { return (*time.Duration)(d).String() }

虽然 time.Duration 没有实现 flag.Value 接口但是. 在函数调用过程中 新建一个 durationValue 类型,并实现了flag.Value 接口. 相当于做了一层拦截.AOP.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题