我正在对一些不可预测的 I/O 进行计时。这段代码
started := time.Now()
time.Sleep(123456789 * time.Nanosecond) // unpredictable process
fmt.Printf("%v", time.Since(started))
产品
123.456789ms
我喜欢自动选择和打印单位刻度(ms、μs、ns 等),因为我事先不知道定时操作是否需要微秒、毫秒或秒才能完成。
我不喜欢这种精度 - 我更愿意只报告两位或三位有效数字。是否有一种简单的方法来限制格式化指令%v
或类似的精度?
最佳答案
前言:我在 github.com/icza/gox
中发布了这个实用程序,请参阅 timex.Round()
。
我认为没有简单的方法,因为当使用默认格式(例如 %v
)打印时,会调用 Duration.String()
来生成字符串表示形式。它返回一个字符串
值,因此小数位数等格式化选项不再适用。
控制结果小数位的一种方法是在打印之前使用 Duration.Truncate()
或 Duration.Round()
截断或舍入持续时间。
当然,持续时间应截断或舍入到的单位取决于持续时间的值,但逻辑并不难:
var divs = []time.Duration{
time.Duration(1), time.Duration(10), time.Duration(100), time.Duration(1000)}
func round(d time.Duration, digits int) time.Duration {
switch {
case d > time.Second:
d = d.Round(time.Second / divs[digits])
case d > time.Millisecond:
d = d.Round(time.Millisecond / divs[digits])
case d > time.Microsecond:
d = d.Round(time.Microsecond / divs[digits])
}
return d
}
让我们用不同的持续时间来测试它:
ds := []time.Duration{
time.Hour + time.Second + 123*time.Millisecond, // 1h0m1.123s
time.Hour + time.Second + time.Microsecond, // 1h0m1.000001s
123456789 * time.Nanosecond, // 123.456789ms
123456 * time.Nanosecond, // 123.456µs
123 * time.Nanosecond, // 123ns
}
for _, d := range ds {
fmt.Printf("%-15v", d)
for digits := 0; digits <= 3; digits++ {
fmt.Printf("%-15v", round(d, digits))
}
fmt.Println()
}
输出将是(在 Go Playground 上尝试):
duration 0 digits 1 digit 2 digits 3 digits
-----------------------------------------------------------------------
1h0m1.123s 1h0m1s 1h0m1.1s 1h0m1.12s 1h0m1.123s
1h0m1.000001s 1h0m1s 1h0m1s 1h0m1s 1h0m1s
123.456789ms 123ms 123.5ms 123.46ms 123.457ms
123.456µs 123µs 123.5µs 123.46µs 123.456µs
123ns 123ns 123ns 123ns 123ns
关于go - 限制格式化持续时间中的有效数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58414820/