Go字符串变量的显示大小似乎不真实。

huangapple go评论83阅读模式
英文:

Displayed size of Go string variable seems unreal

问题

请看这个例子:http://play.golang.org/p/6d4uX15EOQ

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

func main() {
    c := "foofoofoofoofoofofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo"
    fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c))
    fmt.Printf("c: %T, %d\n", c, reflect.TypeOf(c).Size())
}

输出:

c: string, 8 //8字节?!
c: string, 8

看起来这么长的字符串不可能只有这么小的大小!出了什么问题?

英文:

Please see the example: http://play.golang.org/p/6d4uX15EOQ

package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

func main() {
	c := "foofoofoofoofoofofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo"
	fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c))
	fmt.Printf("c: %T, %d\n", c, reflect.TypeOf(c).Size())
}

Output:

c: string, 8 //8 bytes?!
c: string, 8

It seems like so large string can not have so small size! What's going wrong?

答案1

得分: 8

你正在查看的是字符串的顶层描述符,它包含指向底层字符串值的指针和长度。使用len函数可以获取底层字符串值的字节长度。

从概念上和实际上,字符串描述符是一个包含指针和长度的结构体,其长度(32位或64位)取决于具体的实现。例如:

package main

import (
	"fmt"
	"unsafe"
)

type stringDescriptor struct {
	str *byte
	len int
}

func main() {
	fmt.Println("字符串描述符的字节大小:", unsafe.Sizeof(stringDescriptor{}))
}

输出结果(64位系统):

字符串描述符的字节大小:16

输出结果(32位系统):

字符串描述符的字节大小:8
英文:

> Package unsafe
>
> import "unsafe"
>
> func Sizeof
>
> func Sizeof(v ArbitraryType) uintptr
>
> Sizeof returns the size in bytes occupied by the value v. The size is
> that of the "top level" of the value only. For instance, if v is a
> slice, it returns the size of the slice descriptor, not the size of
> the memory referenced by the slice.
>
> The Go Programming Language Specification
>
> Length and capacity
>
> len(s) string type string length in bytes

You are looking at the "top level", the string descriptor, a pointer to and the length of the underlying string value. Use the len function for the length, in bytes, of the underlying string value.

Conceptually and practically, the string descriptor is a struct containing a pointer and a length, whose lengths (32 or 64 bit) are implementation dependent. For example,

package main

import (
	"fmt"
	"unsafe"
)

type stringDescriptor struct {
	str *byte
	len int
}

func main() {
	fmt.Println("string descriptor size in bytes:", unsafe.Sizeof(stringDescriptor{}))
}

Output (64 bit):

<pre>
string descriptor size in bytes: 16
</pre>

Output (32 bit):

<pre>
string descriptor size in bytes: 8
</pre>

答案2

得分: 2

一个字符串本质上是一个指向数据的指针,以及一个表示长度的整数;所以在32位系统上,它占用8个字节,在64位系统上占用16个字节。

英文:

A string is essentially a pointer the the data, and an int for the length; so on 32bit systems, it's 8 bytes, and 16 bytes on 64-bit systems.

答案3

得分: 2

unsafe.Sizeofreflect.TypeOf(foo).Size()都显示字符串头的大小(两个字,如果我没记错的话)。如果你想获取字符串的长度,请使用len(foo)

Playground: http://play.golang.org/p/hRw-EIVIQg.

英文:

Both unsafe.Sizeof and reflect.TypeOf(foo).Size() show the size of the string header (two words, IIRC). If you want to get the length of a string, use len(foo).

Playground: http://play.golang.org/p/hRw-EIVIQg.

huangapple
  • 本文由 发表于 2014年11月18日 00:41:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/26977485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定