golang中,unsafe.sizeof到底是干嘛的?

博主初学Go语言,对获取结构体空间大小有疑问。提到用unsafe.sizeof获取,且它与其他语言的sizeof不同。还询问空结构体空间大小,最后解释在64位系统上,Golang的string内部实现两部分各8字节,共16字节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小生初学Go,有一点不懂,今天为了知道空结构体到底占多大的空间的时候,去百度说用unsafe.sizeof,但是对于unsafe.sizeof好像和其它语言的sizeof有些不一样?

比如:

var str string = "hello"
var str2 string

fmt.Println(unsafe.SizeOf(str), unsafe.SizeOf(str2))

结构两个打印出来都是16,这是为啥?
到底怎样来获取结构体占的空间大小?
空结构体占多大的空间?

共 1 个回复


 

只返回数据类型的大小,不管引用数据的大小,string类型不是直接存的数据,而是一个结构体,用指针指向实际数据地址

type StringHeader struct {
        Data uintptr
        Len  int
}

在64位系统上uintptr int都是8字节,加起来就16了。

https://golang.org/pkg/reflect/#StringHeader

 

 

初步解释:因为Golang中的sring内部实现由两部分组成,一部分是指向字符串起始地址的指针,另一部分是字符串的长度,两部分各是8字节,所以一共16字节

要实现WindTerm中rz命令弹出文件选择框的功能,需要使用go语言编写一个WinAPI程序,并在WindTerm中调用它。以下是基本的代码示例: ```go package main import ( "fmt" "syscall" "unsafe" ) var ( comdlg32 = syscall.NewLazyDLL("comdlg32.dll") getOpenFileName = comdlg32.NewProc("GetOpenFileNameW") getSaveFileName = comdlg32.NewProc("GetSaveFileNameW") ole32 = syscall.NewLazyDLL("ole32.dll") coTaskMemFree = ole32.NewProc("CoTaskMemFree") shell32 = syscall.NewLazyDLL("shell32.dll") dragQueryFileW = shell32.NewProc("DragQueryFileW") dragFinish = shell32.NewProc("DragFinish") shellExecuteExW = shell32.NewProc("ShellExecuteExW") shellNotifyIconW = shell32.NewProc("Shell_NotifyIconW") shellGetImageLists = shell32.NewProc("SHGetImageList") user32 = syscall.NewLazyDLL("user32.dll") sendMessageW = user32.NewProc("SendMessageW") postMessageW = user32.NewProc("PostMessageW") ) type openfilename struct { structSize uint32 hwndOwner uintptr hInstance uintptr filter *uint16 customFilter *uint16 maxCustomFilter uint32 filterIndex uint32 file *uint16 maxFile uint32 fileTitle *uint16 maxFileTitle uint32 initialDir *uint16 title *uint16 flags uint32 fileOffset uint16 fileExtension uint16 defExt *uint16 custData uintptr hook uintptr templateName *uint16 reserved uintptr flagsEx uint32 } func rzFileDialog() (string, error) { var ofn openfilename ofn.structSize = uint32(unsafe.Sizeof(ofn)) ofn.flags |= 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 // OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_ALLOWMULTISELECT | OFN_PATHMUSTEXIST ofn.filter = syscall.StringToUTF16Ptr("All Files (*.*)\x00*.*\x00\x00") ofn.file = syscall.StringToUTF16Ptr(string(make([]uint16, 8192))) ofn.maxFile = uint32(len([]uint16(*ofn.file))) ofn.fileTitle = syscall.StringToUTF16Ptr(string(make([]uint16, 8192))) ofn.maxFileTitle = uint32(len([]uint16(*ofn.fileTitle))) ret, _, _ := getOpenFileName.Call(uintptr(unsafe.Pointer(&ofn))) if ret == 0 { return "", syscall.GetLastError() } defer coTaskMemFree.Call(uintptr(unsafe.Pointer(ofn.file))) defer coTaskMemFree.Call(uintptr(unsafe.Pointer(ofn.fileTitle))) return syscall.UTF16ToString((*[8192]uint16)(unsafe.Pointer(ofn.file))[:]), nil } func main() { file, err := rzFileDialog() if err != nil { fmt.Println("Error:", err) return } fmt.Println("Selected file:", file) } ``` 在WindTerm中,可以使用以下命令来调用此程序: ``` rz | go run filedialog.go ``` 这将在WindTerm中启动rz命令,并弹出文件选择框。选择文件后,程序将在WindTerm中输出所选文件的路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值