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

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
", c, unsafe.Sizeof(c))
    fmt.Printf("c: %T, %d
", 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?

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):

string descriptor size in bytes: 16

Output (32 bit):

string descriptor size in bytes: 8

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.

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.