英文:
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.Sizeof
和reflect.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论