Go 数据结构-字符串

05-30 5,329 views

      每一种语言的数据结构都有差异,都有各自的数据结构。今天来说说Go 数据结构中的字符串。在Go语言中字符串是不可变的字节序列(好像大部分语言数据结构中,字符串类型都是不可改变的.),其本身是一个符合结构。

       咱们首先写一段代码,然后根据这段代码来解析一下Go语言字符串类型。

package main

func main() {
    s := "abcd"
    println(s)
}

字符串内存布局  

        在Go语言中,字符串在内存中的布局是怎么样的呀?



         字符串类型是由两部分组成,由头部指针和长度组成。Go字符串类型没有NULL结尾。字符串类型由长度是16(uint8  + int = 16),uint8 头部指针指向字节数组。

Go字符串数据结构内存布局:



         字符串类型由两块内存组成struct 和 data组成。struct[0] 是一个指针类型,执行底层数组。strcut[1]是该数据的长度。

字符串参数传递:

        现在咱们知道了Go语言中字符串类型是一个复合类型,由两块内存组成。字符串如果作为参数传递给其它函数,该参数在该函数中的内存是怎么分布的哪?接下来,咱们通过gdb调试来看看具体的实现。

按值传递:

package main

func test(s string){
     println(s)
}

func main(){
    s := "abcd"
    test(s)
    println(s)
}

       上面代码中,将变量s作为参数传递给函数test。

gdb 对main函数进行调试:

          main函数中,字符串变量s地址为0xc820033f38,然后该ptr指向0x0000000000472488(即内容地址)地址

gdb对test函数进行调试:

        调用test函数时,将main函数内的s变量作为参数传递给test。所以咱们在test函数查看传进来的参数信息。查看参数s内存地址,该地址为0xc820033f28和main函数内的s变量内存地址不同。但是main函数内变量s和test内的ptr 指针都指向0x0000000000472488地址空间。所以只是进行了函数栈空间创建,指向的底层数据没有发生改变。


按地址传递:

package main

func test(s *string){
    println(s)
}

func main() {
    s := "abcd"
    test(&s)
    println(s)
}

gdb 对main函数进行调试:

gdb 对test函数进行调试:

        现在test参数是通过按内存地址进行传递。查看test函数参数s内存地址,发现s内存地址指向了main函数变量s的内存地址。然后通过该ptr地址访问0x0000000000472488地址内容。

         通过以上两种参数传递方式,咱们可以通过以下两图进行总结。

         

        在此之前,我一直认为Go字符串类型跟C的相同,由一段相连的内存地址组成以\0结束。但是通过今天的调试。发现根本不是那么回事儿。今天由于时间问题,先说到这里。