Golang 之于 DevOps 开发的利与弊(六部曲之四):time 包和方法重载

ArisAries · 2018-03-17 22:41:26 · 1861 次点击 · 预计阅读时间 5 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2018-03-17 22:41:26 的文章,其中的信息可能已经有所发展或是发生改变。

万众期待的 Golang 之于 DevOps 开发的利与弊 系列终于回归了!在这篇文章,我们讨论下 Golang 中的 time 包,以及 go 语言中为什么不使用方法重载。

如果你没有读 最近一篇 关于 “接口实现和公有/私有命名方式”(原文描述写错了,这一链接对应的应该是 “速度 vs. 缺少泛型”),请一定仔细阅读下,你也可以 订阅我们的博客更新,以后有系列文章发布的时候你就能收到通知。

Golang 之利: Time 包的使用

编程的人都知道处理 date 和 time 时候的危险。时间(time)在我们每天的生活中看似平常,可从计算机的角度看,time 处理简直是噩梦。Google 有了这个机会使处理 date 变得轻松点,他们成功了!我将 time 包 的讲解分成了三部分:(1)基本内容,(2)timer 定时器,(3)date 解析。

1. Time 包基本内容

你可能认为每一种语言都有一个标准的,易用的处理 time 操作的内置库,其实不是这样的。NPM 有超过 8000 多个 time 相关的包,因为 javascript 的 Date 包没法用。Java8 最终使用 java.time.Instant 和 java.time.chrono 包缓解了这个问题,但仍在编写 教程,研究各种用 Java 操作 time 的类和方法。相反,Golang 的 time 包 用一句话就能总结:只需引用一个包,你想要的都能实现。

获取当前时间: time.Now()

获取将来某个时刻: time.Now().Add(5*time.Minute)

获取经过多少时间(持续时间):time.Since(processingStarted)

轻松地比较持续时间: if frequency < time.Hour {

获取当月日期,放弃 calendar 吧! time.Now().Day() 就够了

2. Timers 定时器

这个 time 包另一个大的加分项是使用 timer 定时器很方便。DevOps 的应用很明确:我们经常需要安排一些任务在将来执行,一些重复的基本操作,或者就是 sleep 一会。

用 time 包里的 co-locating 定时器,你可以轻松实现 sleep 一个线程,如

time.Sleep(2*time.Minute)

或者在将来的某个时刻执行一个函数

time.AfterFunc(5*time.Second, func() {
    fmt.Println("hello in the future")
})

或者重复执行一个任务

tick := time.NewTicker(1*time.Minute)
select {
case <- tick.C:
    foo()
}

(这些操作)都不需要将时间转换成 second(还是 millsecond 来着?),(也不用)添加 2 个依赖库,(也不用)引入 10 个包。

3. Date 解析

不说下我们最常见又最讨厌的话题:将字符串转成 date ,那关于 time 的讨论就是不完整的。这本该是个初级问题,却一点也不简单。date 格式有 诸多标准编程语言内部并没有一个线程安全的实现 来解析 date 和 timezone,就是为了确保不是所有的地方(同一时刻)都是 5 点钟。这就是 Golang 意识到的重要的地方:其他人做的都是错的。

Google 没有生成解决方案去处理成千上万的 date 格式,而是创建了一套系统,使用基于 pattern 的设计,永远参考同一个参照时间: Mon Jan 02 15:04:05 MST 2006 。组成这个单一参照时间的元素,可以重新组合成任何一种你可能遇到的格式。你可以在这里(原文没有链接,疑似 这里)找到准确,完整的说明。

当然,Golang 的 date 解析也不那么完美,是吧?嗯,当然。你至少要考虑一个问题:timezone ,否则不能重新解析 date。除此之外,安排会议也大不可能了,还是因为 Golang 里的 timezone,让类似 “2017/10/03 4:07:22 America/New_York” 这样的解析比较困难。“America/New_York” 这几个 bit (解析起来)比较麻烦。有一些 变通的解决办法,不过 Golang 在解析 timezone 这部分还需要改进。

Golang 之弊: 函数重载

我想起上计算机科学课时候的事,第一感觉就是“太酷了!”,但是在 Golang 里完全不存在这种“酷”。以下来自 Golang FAQ:

为什么 Go 不支持方法和操作符重载? 如果不用做类型匹配,方法调度过程也会简化。使用其他语言的经验告诉我们,一些有着同名但不同签名的函数有时候很有用,不过实际使用中也会造成误解,不够健壮。 Go 类型系统主要使用的简化决策是只通过函数名匹配,并且要求类型的一致性。就操作符的重载来说,似乎比绝对要求(类型一致性)方便。 不过还是,没有重载会更简单。

当然,没有方法重载确实更简单。但这样也会强制你想出唯一的函数名以防出现同名函数,这样一来就增大了你的代码量。如果你只是想复制粘贴下代码,“以后再解”,还要记住共用函数是在私有的还是公共函数起作用。后面提到的 time 包有几个这样的实例,我们特别想用一个默认值替代最后那个可选参数。

func Parse(layout, value string) (Time, error) { 
    return parse(layout, value, UTC, Local)
}

func ParseInLocation(layout, value string, loc *Location) (Time, error) {
    return parse(layout, value, loc, loc)
}

func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
    ...
}

[源代码地址]

这就是说,没有方法重载绝不妨碍使用 Golang。在几个我想用(重载)的实例中,我最终只用了一个共用的私有函数,和其它几个不同名字的函数,或是删除了我一开始说需要重载的原因。

每隔一周左右,我们会发布一篇新指南,和本篇一样都在 “Golang 之于 DevOps 开发的利与弊” 六部曲中。下一篇:#5:跨平台编译, Windows , Signals ,Docs 和编译器。

现在起 订阅我们的博客吧,这样你就不会错过我们的文章发布了,如果你觉得你的开发者朋友们能受益于了解 Golang 的利与弊,请把这篇博文分享给他们,尤其是有关 DevOps 生命周期的。感谢您阅读和分享。


via: https://blog.bluematador.com/golang-pros-cons-part-4-time-package-method-overloading

作者:Matthew Barlocker  译者:ArisAries  校对:polaris1119

本文由 GCTT 原创编译,Go语言中文网 荣誉推出


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1861 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传