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?
import "unsafe"
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
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.