为了测试并发goroutine,我在函数中添加了一行,使其需要一段随机时间返回(最多一秒)
time.Sleep(rand.Int31n(1000) * time.Millisecond)
Run Code Online (Sandbox Code Playgroud)
但是当我编译时,我收到了这个错误
.\ crawler.go:49:无效操作:rand.Int31n(1000)*time.Millisecond(不匹配类型int32和time.Duration)
有任何想法吗?我如何乘以持续时间?
mna*_*mna 370
int32
并且time.Duration
是不同的类型.你需要将其转换int32
为a time.Duration
,例如time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
.
Sal*_*ali 47
您必须将其转换为正确的格式Playground.
yourTime := rand.Int31n(1000)
time.Sleep(time.Duration(yourTime) * time.Millisecond)
Run Code Online (Sandbox Code Playgroud)
如果您要检查睡眠文档,您会发现它需要func Sleep(d Duration)
持续时间作为参数.你的rand.Int31n回来了int32
.
示例中的行work(time.Sleep(100 * time.Millisecond)
)因为编译器足够聪明,可以理解这里的常量 100表示持续时间.但是如果你传递一个变量,你应该抛出它.
Geo*_*voy 13
在Go中,您可以将相同类型的变量相乘,因此您需要使表达式的两个部分具有相同的类型.
你可以做的最简单的事情是在乘法之前将一个整数转换为持续时间,但这会违反单位语义.在单位方面,持续时间乘以持续时间是多少?
我宁愿将time.Millisecond转换为int64,然后将其乘以毫秒数,然后转换为time.Duration:
time.Duration(int64(time.Millisecond) * int64(rand.Int31n(1000)))
Run Code Online (Sandbox Code Playgroud)
这样,表达式的任何部分都可以说根据其类型具有有意义的值.int64(time.Millisecond)
part只是一个无量纲值 - 原始值中最小时间单位的数量.
如果走一条稍微简单的路径:
time.Duration(rand.Int31n(1000)) * time.Millisecond
Run Code Online (Sandbox Code Playgroud)
乘法的左边部分是无意义的 - 类型为"time.Duration"的值,保留与其类型无关的内容:
numberOfMilliseconds := 100
// just can't come up with a name for following:
someLHS := time.Duration(numberOfMilliseconds)
fmt.Println(someLHS)
fmt.Println(someLHS*time.Millisecond)
Run Code Online (Sandbox Code Playgroud)
它不仅仅是语义,还有与类型相关的实际功能.此代码打印:
100ns
100ms
Run Code Online (Sandbox Code Playgroud)
有趣的是,这里的代码示例使用最简单的代码,具有与持续时间转换相同的误导性语义:https://golang.org/pkg/time/#Duration
秒:= 10
fmt.Print(time.Duration(seconds)*time.Second)//打印10秒
Cat*_*tsy 11
Duration
对乘以的一些评论和讨论感到困惑Duration
,我玩了一下单位和函数并得到了这个:
time.Second = 1s
time.Minute = 1m0s
time.Duration(1) = 1ns
time.Duration(1) * time.Millisecond = 1ms
time.Duration(1) * time.Second = 1s
time.Duration(1) * time.Minute = 1m0s
Run Code Online (Sandbox Code Playgroud)
很高兴 Go 有一个Duration
类型——明确定义的单位可以防止现实世界中的问题。
而且由于 Go 的严格类型规则,您不能将 Duration 乘以整数——您必须使用强制转换才能乘以常见类型。
/*
MultiplyDuration Hide semantically invalid duration math behind a function
*/
func MultiplyDuration(factor int64, d time.Duration) time.Duration {
return time.Duration(factor) * d // method 1 -- multiply in 'Duration'
// return time.Duration(factor * int64(d)) // method 2 -- multiply in 'int64'
}
Run Code Online (Sandbox Code Playgroud)
在官方文档演示了使用方法1:
要将整数单位转换为持续时间,请乘以:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
Run Code Online (Sandbox Code Playgroud)
但是,当然,将持续时间乘以持续时间不应产生持续时间——从表面上看,这是荒谬的。例如,5 毫秒乘以 5 毫秒会产生6h56m40s
. 尝试平方 5 秒会导致溢出(如果使用常量完成,甚至不会编译)。
顺便说一下,以纳秒int64
为Duration
单位的表示“将最大的可表示持续时间限制为大约 290 年”,这表明Duration
像 一样int64
被视为有符号值:(1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
,这正是它的实现方式:
// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64
Run Code Online (Sandbox Code Playgroud)
所以,因为我们知道 的底层表示Duration
是int64
,在int64
和之间执行转换Duration
是一个明智的 NO-OP —— 只需要满足关于混合类型的语言规则,它对后续的乘法运算没有影响。
如果您出于纯度的原因不喜欢铸造,请将其埋在函数调用中,如我上面所示。
归档时间: |
|
查看次数: |
128180 次 |
最近记录: |