Go基础数据结构学习——string

Go基础数据结构学习——string

  1. string在Go语言内存模型中用一个2字长的数据结构表示,一个是指向字符串存储的数据的指针,另一个为长度数据。

    type stringStruct struct {
    	str unsafe.Pointer
    	len int
    }
    
  2. 由于string中不包含内存空间,只有一个内存的指针,可以方便的进行传输而不用担心内存拷贝,非常的轻量化,但是字符串字面量存储位置是只读段的,不是在堆或者栈上,所以string是不可修改的

  3. string和[]byte相互转换,需要内存拷贝(申请内存空间=>拷贝数据),[]byte擅长与字符串修改和切片操作的场景,string擅长与字符串比较和不需要nil的场景

  4. 注意:

    • string默认值是“”,而不是nil

    • string不能和nil比较

    • len获取到的是字符串的字节数而不是字符串的字符数

      对于ascii字符,一个字符占一个字节;对于非ASCII字符,比如汉字,一个字符就占3个字节。如字符串“hello北京”,它的字符长度是7,但它的字节长度是11

    • Index遍历的时候也是字节遍历的,所以中文遍历会有乱码问题

    • for-range是字符遍历的,不会出现乱码,但是下标index就有出现不连续的问题

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPcw0B45-1586877765381)(/Users/hexiaohong/Library/Application Support/typora-user-images/image-20200414224923063.png)]

  5. 字符串的拼接

    字符串的评价有很多种方式,比如:

    • 使用“+”

      hello := "hello"
      world := "world"
      helloWorld := hello + "," + world
      // 每次+都会产生新的临时字符串,会给 gc 带来负担,性能比较差
      
    • 使用fmt.Sprintf

      hello := "hello"
      world := "world"
      helloWorld := fmt.Sprintf("%s,%s", hello, world)
      // 可以用于有数字或其他的拼接,因为其他的额外判断,性能也比较差
      
    • strings.Join()

      hello := "hello"
      world := "world"
      helloWorld := strings.Join([]string{hello, world}, ",")
      // join会先根据字符串数组,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高
      
    • 使用buffer.WriteString()

      hello := "hello"
      world := "world"
      var buffer bytes.Buffer
      buffer.WriteString(hello)
      buffer.WriteString(",")
      buffer.WriteString(world)
      helloWorld := buffer.String()
      // 性能最好
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章