zoukankan      html  css  js  c++  java
  • Go语言 字符串

    字符串

    简介

      一个字符串是一个不可改变的字节序列,字符串通常是用来包含人类可读的文本数据。和数组不同的是,字符串的元素不可修改,是一个只读的字节数组。每个字符串的长度虽然也是固定的,但是字符串的长度并不是字符串类型的一部分。由于Go语言的源代码要求是UTF8编码,导致Go源代码中出现的字符串面值常量一般也是UTF8编码的。

      Go语言字符串底层数据也是对应的字节数组,但是字符串的只读属性禁止了在程序中对底层字节数组的元素的修改。字符串赋值只是复制了数据地址和对应的长度,而不会导致底层数据的复制(重点!!

    初始化

    package main
    
    import "fmt"
    
    func main() {
    	// 第一种方式
    	var str1 string
    	str1 = "string"
    	// 第二种方式
    	var str2 = "string"
    	// 第三种方式
    	str3 := "string"
    
    	fmt.Println(str1)
    	fmt.Println(str2)
    	fmt.Println(str3)
    }
    
    //string
    //string
    //string
    

      

    底层结构

    Go语言字符串的底层结构在reflect.StringHeader中定义:

    type StringHeader struct {
        Data uintptr
        Len  int
    }
    

    字符串结构由两个信息组成:第一个是字符串指向的底层字节数组,第二个是字符串的字节的长度。字符串其实是一个结构体,因此字符串的赋值操作也就是reflect.StringHeader结构体的复制过程,并不会涉及底层字节数组的复制。可以将字符串数组看作一个结构体数组。

    我们可以看看字符串“Hello, world”本身对应的内存结构:

    分析可以发现,“Hello, world”字符串底层数据和以下数组是完全一致的:

    var data = [...]byte{
        'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd',
    }

    验证:

    package main
    
    import (
    	"fmt"
    	"reflect"
    	"unsafe"
    )
    
    func main() {
    	str := "hello, world"
    	data := [...] byte{'G','o'}
    	fmt.Println(str)
    	fmt.Println(&str)
    	hdr :=(*reflect.StringHeader)(unsafe.Pointer(&str))
    	hdr.Data = uintptr(unsafe.Pointer(&data[0]))
    	hdr.Len = len(data)
    	fmt.Println(str)
    	fmt.Println(&str)
    }
    
    //hello, world
    //0xc0000321d0
    //Go
    //0xc0000321d0
    

     

    切片

    字符串虽然不是切片,但是支持切片操作,不同位置的切片底层也访问的同一块内存数据(因为字符串是只读的,相同的字符串面值常量通常是对应同一个字符串常量):

    package main
    
    import "fmt"
    
    func main() {
    	s := "hello, world"
    	hello := s[:5]
    	world := s[7:]
    
    	fmt.Println(hello)
    	fmt.Println(world)
    }
    
    //hello
    //world
    

      

     

  • 相关阅读:
    使用vue-cli搭建SPA项目
    NodeJS的环境搭建+传统ELmentui+vue开发
    vue路由
    Vue基础语法(样式绑定,事件处理,表单,Vue组件)
    动态规划 | 保留重复元素的LCS 1045
    动态规划 | 1007 最大连续子序列和
    数学问题 | 质因数分解:1096
    数学问题 | 连续质因数分解:1096
    数据结构 | 哈希表二次探查法 : 1078
    数学问题 | 1015 进制转换与素数问题
  • 原文地址:https://www.cnblogs.com/lianzhilei/p/11521468.html
Copyright © 2011-2022 走看看