Golang中为何字符串的sizeof返回16字节,而int和float默认只占8字节?且指针地址为何是8字节?

Golang中为何字符串的sizeof返回16字节,而int和float默认只占8字节?且指针地址为何是8字节? 为什么字符串的 sizeof 结果是 16 字节,而 int 和 float 默认只有 8 字节?另外,任何指针(int、float、string)的地址都占用 8 字节。

能否有人给出详细的解释?提前感谢…!!! 下面附上了示例代码和输出以供参考。

示例代码

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    a := "Hello\n"
    fmt.Println(a, &a)
    fmt.Printf("address %T value %T Addresssize : %d and values size : %d", &a, a, unsafe.Sizeof(&a), unsafe.Sizeof(a))
}

输出:

Hello
0xc000010230
address *string value string Addresssize : 8 and values size : 16

更多关于Golang中为何字符串的sizeof返回16字节,而int和float默认只占8字节?且指针地址为何是8字节?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

从内存角度来看,字符串占用16个字节:8个字节用于指向底层字节数组的指针(您无法直接访问它),另外8个字节用于存储字节数组的长度。

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	a := "Hello\n"
	var aRuneCounter uint8
	for range a {
		aRuneCounter++
	}
	b := int8(2)
	c := int32(332)
	d := int64(23453)
	e := "ąśóąśąłłęóąśa"
	var eRuneCounter uint8
	for range e {
		eRuneCounter++
	}
	fmt.Println(a, &a)
	fmt.Printf("address %T value %T Addresssize : %d and values size : %d len: %d rune counter: %d, %#v\n", &a, a, unsafe.Sizeof(&a), unsafe.Sizeof(a), len(a), aRuneCounter, []byte(a))
	fmt.Printf("address %T value %T Addresssize : %d and values size : %d\n", &b, b, unsafe.Sizeof(&b), unsafe.Sizeof(b))
	fmt.Printf("address %T value %T Addresssize : %d and values size : %d\n", &c, c, unsafe.Sizeof(&c), unsafe.Sizeof(c))
	fmt.Printf("address %T value %T Addresssize : %d and values size : %d\n", &d, d, unsafe.Sizeof(&d), unsafe.Sizeof(d))
	fmt.Printf("address %T value %T Addresssize : %d and values size : %d len: %d rune counter: %d, %#v\n", &e, e, unsafe.Sizeof(&e), unsafe.Sizeof(e), len(e), eRuneCounter, []byte(e))

}

更多关于Golang中为何字符串的sizeof返回16字节,而int和float默认只占8字节?且指针地址为何是8字节?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,unsafe.Sizeof()返回的是类型在内存中占用的字节数。以下是详细解释:

1. 字符串结构(16字节)

Go的字符串底层是一个结构体,包含两个字段:

type stringStruct struct {
    str unsafe.Pointer  // 8字节:指向底层字节数组的指针
    len int             // 8字节:字符串长度
}

因此unsafe.Sizeof(string)总是返回16字节,无论字符串内容多长。

2. int和float(8字节)

在64位系统上:

  • intfloat64默认都是8字节
  • int32float32是4字节
  • 大小由架构决定:int在32位系统是4字节,64位系统是8字节

3. 指针地址(8字节)

在64位系统上,所有指针都是8字节,因为:

  • 内存地址用64位(8字节)表示
  • 无论指向什么类型(*int*string*float64),指针本身大小相同

验证示例:

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    // 基本类型大小
    fmt.Printf("int: %d bytes\n", unsafe.Sizeof(int(0)))           // 8
    fmt.Printf("float64: %d bytes\n", unsafe.Sizeof(float64(0)))   // 8
    fmt.Printf("string: %d bytes\n", unsafe.Sizeof(""))            // 16
    
    // 指针大小
    var i int
    var s string
    var f float64
    fmt.Printf("*int: %d bytes\n", unsafe.Sizeof(&i))              // 8
    fmt.Printf("*string: %d bytes\n", unsafe.Sizeof(&s))           // 8
    fmt.Printf("*float64: %d bytes\n", unsafe.Sizeof(&f))          // 8
    
    // 字符串结构验证
    str := "Hello"
    strPtr := (*struct {
        ptr unsafe.Pointer
        len int
    })(unsafe.Pointer(&str))
    
    fmt.Printf("String pointer: %v\n", strPtr.ptr)
    fmt.Printf("String length: %d\n", strPtr.len)
}

输出示例(64位系统):

int: 8 bytes
float64: 8 bytes
string: 16 bytes
*int: 8 bytes
*string: 8 bytes
*float64: 8 bytes
String pointer: 0x4c3b20
String length: 5

总结:字符串的16字节来自其底层结构(8字节指针+8字节长度),指针统一8字节是64位系统的寻址需求,int/float的大小由类型和架构共同决定。

回到顶部