前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WTF Go: Constants

WTF Go: Constants

作者头像
布鲁斯鱼
发布2022-11-02 14:11:33
3830
发布2022-11-02 14:11:33
举报
文章被收录于专栏:布鲁斯鱼的妙想天开
代码语言:javascript
复制
import (
	"time"
	"math/rand"
)

// invalid operation: rand.Intn(10) * 1000 * time.Millisecond (mismatched types int and time.Duration)
time.Sleep(rand.Intn(10) * 1000 * time.Millisecond) ❌

// 🤔 make sense.
time.Sleep(time.Duration(rand.Intn(10) * 1000) * time.Millisecond) ✅

// wtf ?!
time.Sleep(1000 * time.Millisecond) ✅ 

看看上面这个简单的例子:

  • 第一个错误很容易理解: 整型不能和 time.Duration 相乘
  • 第二个例子修正了这一问题,符合预期
  • 第三个例子带来了疑问,为什么 1000 * time.Millisecond 却没有问题?明明 1000 也是个整型?编译器戴了有色眼镜?

别慌,仔细看看 rand.Intn(10) * 10001000 的区别在于:前者是变量,类型已经确定了,通不过编译是情理之中;而后者是常量,类型并不是 int ,属于 untyped constants ,编译器会尝试将它转换成 time.Duration

这就勾起了我的好奇心,那如果我写个一个 float 常量会怎样呢?

代码语言:javascript
复制
// (untyped float constant) truncated to int64
time.Sleep(1000.1 * time.Millisecond) ❌

果然是不行的。那么究竟这个无类型常量的类型转换是依照什么规则进行的呢?

首先每一种常量的写法都会对应着一种默认类型:

notion image
notion image

然后,看看 time.Duration 的定义:

代码语言:javascript
复制
type Duration int64

const (
    Nanosecond  Duration = 1
    Microsecond          = 1000 * Nanosecond
    Millisecond          = 1000 * Microsecond
    Second               = 1000 * Millisecond
    Minute               = 60 * Second
    Hour                 = 60 * Minute
)

也就是说 1000 的写法默认类型为 int ,编译器会尝试做一次类型转换 inttime.Duration ,而 int64int 又能做到完全兼容,所以编译通过。

WTF,Go…

参考:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 10 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档