Golang time.Time应该使用值传递还是指针引用传递

举报
张俭 发表于 2023/12/30 11:24:45 2023/12/30
【摘要】 TLTR大部分场景应该使用值传递。 正文Go 的文档指出Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time...

TLTR

大部分场景应该使用值传递。

正文

Go 的文档指出

Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time. A Time value can be used by multiple goroutines simultaneously.

翻译一下就是

程序使用times典型场景应该把它们当做值传递,而非指针。也就是说time变量及结构体field应该为time.Time,而不是*time.Time。Time值是协程安全的。之所以说typically,是因为有着那么不typically的场景,比如你想在方法内修改原来的time.Time对象这种场景(很少见)。

time.Time是一个较小的对象,把它作为值传递是完全合理的。传递指针而不是值的很重要的一个原因是避免昂贵的拷贝动作。但是传递指针也会给gc带来一些额外的开销,如逃逸分析等。

值得一提的是,你可以通过go build -gcflags="-m"来判断变量在堆中还是在栈中。

image.png

time.Time在我的MBP上只有24个字节。附上几个简单类型的字节数

byte size is  1
int32 size is  4
int size is  8
int64 size is  8
float32 size is  4
float64 size is  8
time size is  24

测试程序

package demo_base

import (
	"fmt"
	"testing"
	"time"
	"unsafe"
)

func TestSize(t *testing.T) {
	{
		var x byte = 0
		fmt.Println("byte size is ", unsafe.Sizeof(x))
	}
	{
		var x int32 = 0
		fmt.Println("int32 size is ", unsafe.Sizeof(x))
	}
	{
		var x int = 0
		fmt.Println("int size is ", unsafe.Sizeof(x))
	}
	{
		var x int64 = 0
		fmt.Println("int64 size is ", unsafe.Sizeof(x))
	}
	{
		var x float32 = 0
		fmt.Println("float32 size is ", unsafe.Sizeof(x))
	}
	{
		var x float64 = 0
		fmt.Println("float64 size is ", unsafe.Sizeof(x))
	}
	{
		t := time.Now()
		fmt.Println("time size is ", unsafe.Sizeof(t))
	}
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。