duration

更新时间:2023-01-01 16:46:15 阅读: 评论:0


2023年1月1日发(作者:赛车总动员3)

记⼀次go语⾔使⽤on类型踩过的坑

⽬录

01踩到的坑

on的真实⾯⽬

03问题解决

on编程实践

05总结

01踩到的坑

先来说说在项⽬中踩到的使⽤on类型的坑。我们的背景是要做⼀个延时任务。延时任务就是指将⼀个任务延迟到⼀

定的时间后再执⾏,所以就需要根据延时时间计算出该任务要执⾏的时间。我们这⾥的延时时间以毫秒为单位,当时我们定义

的是500毫秒。即设置了⼀个全局的变量on。即interval=500*econds。然后就通过以下公式来

计算要

执⾏的时间了:

可执⾏时间=当前时间+延迟时间可执⾏时间=当前时间+延迟时间可执⾏时间=当前时间+延迟时间

由以上公式可得到我们的⼀个任务的可执⾏时间为().UnixMilli()+int64(interval)。⼤家看这⾥有什么问题吗?

问题在于计算的结果值不是在当前的毫秒数上增加了500,⽽是增加了500000000,多了6个零。这是为什么呢?

on的真实⾯⽬

我们从源码中找到答案。我们从time包中看到on的定义:

//ADurationreprentstheelapdtimebetweentwoinstants

//rentationlimitsthe

//largestreprentabledurationtoapproximately290years.

typeDurationint64

由源码可知,Duration本质上是⼀个int64的类型。从注释可知,代表的是两个时间点之间持续的纳秒数。所以这⾥有两点信

息:⼀是该类型代表的是⼀段持续时间,⼆是该类型的基本单位是纳秒。这⾥我先重点关注基本单位是纳秒这点。我们再来

看⼏个常量的定义:

const(

NanocondDuration=1

Microcond=1000*Nanocond

Millicond=1000*Microcond

Second=1000*Millicond

Minute=60*Second

Hour=60*Minute

)

⼀个单位的Duration是代表1纳秒。⽽econd、econd、、、的单位实

际上都是纳秒。也就是说我们使⽤到的econd实际上是1000000纳秒。所以就有了

interval=500*econd=500*1000000=500000000,然后在计算延时后的执⾏时间时两个单位不⼀样造成计算出来

的值不是预期的增加500毫秒的结果。

03问题解决

知道了on类型的基本单位是代表纳秒之后,我们就可以很好的解决了。就是统⼀单位。

我们也发现,在time包中对于on类型的对象有转换成秒、毫秒等对应的函数。如下:

所以我们直接获取即可:

可执⾏时间:=().UnixMilli()+econd()

on编程实践

上⾯是我在编码时因为没搞懂on类型的本质含义猜到的⼀个坑。那么我们在实际编码时在定义和持续时间有关的变

量时应该使⽤int类型还是on类型呢?

我的建议是⼤家尽量⽤on类型。为什么呢?第⼀个原因是和标准库类型统⼀,不⽤做过多的转换。因为我们观察可

以发现,⽆论是开源程序,还是go的标准库,凡是和持续时间相关的变量类型都是使⽤的on,这样类型统⼀我们

来看⼏个例⼦。

⽰例⼀:meout

funcWithTimeout(parentContext,on)(Context,CancelFunc){

returnWithDeadline(parent,().Add(timeout))

}

我们看到,context包中的WithTimeout函数中的timeout的类型是on。

⽰例⼆:

funcSleep(dDuration)

time包中的Sleep函数的d参数也是Duration类型。

⽰例三:ker

funcNewTicker(dDuration)*Ticker

如果我们⾃⼰的程序中相关变量使⽤的也是on类型,那么在调⽤标准库函数时就不⽤进⾏类型转化了。

第⼆个原因就是该类型在语义上就明确了on类型值的基本单位是纳秒。这样在函数调⽤过程中就不⽤进⾏单位换算

了。我们看下⾯以连接redis的⽰例是如何进⾏类型转换的。

我们在连接redis的时候,⼀般都会设置读写超时时间以及定义redis的地址,我们有如下配置:

typeconfigstruct{

Addrstring

ReadTimeoutint64//以秒为单位

}

我们使⽤包/go-redis/redis/v8包来连接redis。我们看到

funcNewRedisClient(confconfig)*{

opt:=s{

Addr:,

ReadTimeout:meout*

}

client:=ent(opt)

returnclient

}

我们知道s中的ReadTimeout的类型是on。那么,如果我们在config配置⽂件中定义的int64类型以秒为

单位的话,则在NewRedisClient中给s中的ReadTimeout赋值时,需要做如下转换:

meout*

那如果我们在config中定义的ReadTimeout的代表的是毫秒的话,那么在NewRedisClient函数中就需要做如下转换:

meout*econd

那在config结构体中的ReadTimeout所代表的含义是秒还是毫秒还是其他的由谁来保证呢,只能是⼈为的进⾏保证。⽽如果使

⽤on类型就是由系统类型来保证的,因为go的标准库定义的该类型就是代表纳秒数。

05总结

本⽂从在实际编程中遇到的问题出发,了解到on类型实际代表的是持续的纳秒数。同时⼜分析了使⽤on

类型的好处。在项⽬中,如果遇到和持续时间相关的变量的定义,也建议⼤家尽量使⽤on类型。

到此这篇关于记⼀次go语⾔使⽤on类型踩过的坑的⽂章就介绍到这了,更多相关on内容请搜索以前的

⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

本文发布于:2023-01-01 16:46:15,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/73071.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:illustration
下一篇:ram是什么
标签:duration
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图