go语言 string数据类型格式

作者: CodingCode | 来源:发表于2017-08-31 13:36 被阅读22次

在go语言里面定义字符串如下:
var ss string = "12345"

对于一个熟悉C/C++的程序员来说,马上就会想到这个string是一个什么内容,占多大空间,内存如何分配等,下面我们来分析这个问题。

go语言的string是一种数据类型,这个数据类型占用16字节空间,前8字节是一个指针,指向字符串值的地址,后八个字节是一个整数,标识字符串的长度;注意go语言的字符串内部并不以'\0'作为结尾,而是通过一个长度域来表示字符串的长度。

type mystr struct {
    strbuf uintptr;
    strlen uint64;
}

上述就是string的类型定义。下面我们通过代码来验证这个问题:

package main

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

type mystr struct {
    strbuf uintptr;
    strlen uint64;
}

func printmemory(p uintptr, size int) {
    fmt.Printf("[0x%16x:%2d] =", p, size)
    for i := 0; i < size; i++ {
        p1 := unsafe.Pointer(p + uintptr(i))
        p2 := (*byte)(unsafe.Pointer(p1))
        fmt.Printf(" %x", *p2)
    }
    fmt.Printf("\n")
}

func main() {
    var ss string = "12345";

    fmt.Printf("string=%v\n", ss)
    fmt.Printf("length=%v\n", len(ss))
    fmt.Printf("size=%v\n", unsafe.Sizeof(ss))
    fmt.Printf("address=%v\n", &ss)

    ptr := unsafe.Pointer(&ss)
    //value := reflect.ValueOf(&ss)
    //fmt.Println(reflect.TypeOf(value), reflect.ValueOf(value).Kind())
    //ptr1 := value.Pointer()
    ptr1 := uintptr(ptr)
    printmemory(ptr1, 16);

    ptr2 := (* mystr)(ptr)
    fmt.Printf("mystr.strbuf=%x\n", ptr2.strbuf)
    fmt.Printf("mystr.strlen=%v\n", ptr2.strlen)
    printmemory(ptr2.strbuf, len(ss)+1);
}

执行结果如下:

$ go build main.go && ./main 
string=12345
length=5
size=16
address=0xc42000e2c0
[0x      c42000e2c0:16] = f1 70 4a 0 0 0 0 0 5 0 0 0 0 0 0 0
mystr.strbuf=4a70f1
mystr.strlen=5
[0x          4a70f1: 6] = 31 32 33 34 35 31

我们看到string的内存结构,包含一个指向字符串数据的指针,和一个标识字符串长度的整数值;而且字符串的结尾并没有一个'\0'来标识,在上述例子中是一个随机值(0x31)。

关于go语言的指针操作

go语言指针和C/C++指针的唯一差别就是:go语言不允许对指针做算术运算(+、-、++、--)。

但是,Go 提供了一套底层库 reflect 和 unsafe,它们可以把任意一个 go 指针转成 uintptr类型的值,然后再像 C/C++一样对指针做算术运算,最后再还原成 go 类型。所以从这个角度上看,go 指针也是可以和 C/C++ 指针一样使用的,只是会比较绕,这同时也要求使用者自己明白,如果真要把指针这么用,那么请记得后果自负。

下面是一个go语言指针运算的例子:
https://play.golang.org/p/z_GMnh38Z1

相关文章

  • go语言 string数据类型格式

    在go语言里面定义字符串如下:var ss string = "12345" 对于一个熟悉C/C++的程序员来说,...

  • 02-Go语言常量和变量

    Go语言的数据类型 C语言的数据类型 Go语言的数据类型 Go语言各数据类型占用内存空间 Go语言中也可以使用si...

  • 变量的基本使用

    如何定义变量? C语言定义变量的格式: 数据类型 变量名称; Go语言中定义变量的格式: var 变量名称 ...

  • Go之旅-变量

    Go语言变量有固定的数据类型,决定了变量内存的长度和存储格式。Go变量只能修改变量值,不能改变变量的数据类型。Go...

  • 04-Go语言常量和变量

    Go数据类型 C语言的数据类型image GO语言数据类型image GO数据类型占用的内存空间image 注意点...

  • go语言slice数据类型的定义和使用

    这篇文章介绍go语言slice数据类型的定义,内部格式,以及如何声明和定义slice类型变量。 slice数据类型...

  • 初识Go语言-1

    Go语言学习路径 初识Go语言 Go语言环境搭建与IDE安装 Go语言基础语法 Go语言数据类型 Go语言变量和常...

  • 05-Go语言常量和变量-指趣学院

    Go语言数据类型 Go语言本质是用C语言编写的一套高级开发语言, 所以Go语言中的数据类型大部分都是由C语言演变而...

  • go 语言第一节课(2)

    go 语言数据类型

  • Go语言第3天 - 常用数据类型

    以下内容部分参考自Go语言基础数据类型Go语言中的数组切片:特立独行的可变数组Go语言数据类型-数组Go标准容器之...

网友评论

    本文标题:go语言 string数据类型格式

    本文链接:https://www.haomeiwen.com/subject/bekqjxtx.html