1、 string的定义
golang中的string的定义在reflect包下的value.Go中,定义如下:
StringHeader 是字符串的运行时表示,其中包含了两个字段,分别是指向数据数组的指针和数组的长度。
2、string不可变
Golang中的字符串是不可变的,不能通过索引下标的方式修改字符串中的数据:
运行代码,可以看到编译器报错,string是不可变的
但是能不能进行一些骚操作来改变元素的值呢?
在上面的代码中,因为在go语言中不能进行指针的加减运算,因此取切片,让b的Data指针指向’,'所在的位置。然后把"hello,world"中的逗号改为点,但是发现还是不行,程序直接崩溃了。看来go语言中的指针得到了大大的限制,设计者并不想让程序员过度使用指针来写出一些不安全的代码。
3、使用string给另一个string赋值
Golang中的字符串的赋值并不是拷贝底层的字符串数组,而是数组指针和长度字段的拷贝。例如:当我们定义了一个字符串 a := “hello,world” 然后定义了 b := a 底层所做的操作只是创建了两个StringHeader的结构体,它们的Data字段都指向同一段数据,如下图:
我们可以利用代码来证实这一点:
在上面的代码中,将a和b转换为StringHeader类型的指针,然后分别打印出,a和b的Data指针的值,发现是相同的
那么如果对a做切片赋值给b呢?
0xd4d849 - 0xd4d84f = 0x000006
显然,也没有分配新的数组并拷贝数据,而是将原字符数组的指针的偏移赋给了b的StringHeader的Data
4、string重新赋值
如果对一个已经赋值的字符串重新赋值,也不会修改原内存空间,而是申请了新的内存空间,对其赋值,并指向新的内存空间。如下图:
也可以使用代码来证实一下:
补充:字符串拼接
字符串可以很方便的拼接,像下面这样:
str := "Str1" + "Str2" + "Str3"
即便有非常多的字符串需要拼接,性能上也有比较好的保证,因为新字符串的内存空间是一次分配完成的,所以性能消耗主要在拷贝数据上。
一个拼接语句的字符串编译时都会被存放到一个切片中,拼接过程需要遍历两次切片,第一次遍历获取总的字符串长度,据此申请内存,第二次遍历会把字符串逐个拷贝过去。
字符串拼接伪代码如下:
因为string是无法直接修改的,所以这里使用rawstring()方法初始化一个指定大小的string,同时返回一个切片,二者共享同一块内存空间,后面向切片中拷贝数据,也就间接修改了string。
rawstring()源代码如下:
总结
到此这篇关于Golang基础教程之字符串string实例详解的文章就介绍到这了,更多相关Golang字符串string详解内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!