19

string

 4 years ago
source link: https://www.tuicool.com/articles/nA7z6bv
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

基础

1 .字符串是一个不可改变的字节序列,一系列8位字节的集合

2 .字符串可以包含任何的数据,包括byte和0.

3 .字符串是一种值类型,且值不能改变,创建某个文本之后无法再次改变这个文本的内容

4 .字符串是字节的定长数组

5 .传统过的字符串是由字符组成的,go的字符串是单个字节链接起来的数组

6 .字节使用utf编码的Unicode文本

7 .字符串底层就是Byte数组

8 .[]byte方法和[]rune方法就是将字符串转化成对应类型的slice

9 .字符串常量一般使用单引号括起来的单个字符

10 .在golang中,字符,字符串中打印单个字符的本质就是一个整数,是改字符对应的utf-8编码的码值

11 .可以给某个变量赋一个数字,然后格式化初始时%c,会输出对应数字的unicode字符

12 .因为字符的本质时一个整数,所以字符类型是可以计算的。

13 .字符-计算机:字符-对应码值-二进制

14 .计算机-字符:二进制-码值-字符

type stringStruct struct {
    str unsafe.Pointer
    len int
}
//str:指向某个数组的指针

字符串类型

1 .解释型字符串

1 .使用双引号包起来,其中的转义字符串将被替换
2 .\n
3 .\r
4 .\t
5 .\u
6 .\\

2 .非解释字符串

1 .使用``包起来.支持换行
2 .

字符串基于UTF8编码

1 .通过rune类型,可以方便的对每个UTF8字符进行访问

2 .

s:="123 飞机"
    b:=[]byte(s)
    for _,v:=range b{
        fmt.Printf("%v \n",v)       
    }
    fmt.Println(string(b))
    for _,v:=range s{
        fmt.Printf("%c \n",v)
    }
    for _,v:=range []rune(s){
        fmt.Printf("%c \n",v)
    }

字符串的长度

1 .len:计算切片,字符串,通道的长度。返回值的类型为 int,表示字符串的 ASCII 字符个数或字节长度.ASCII 字符串长度使用 len() 函数。

2 .统计utf8字符串的长度.Unicode 字符串长度使用 utf8.RuneCountInString() 函数

字符串遍历

1 .不管是asicc还是utf8都使用for range就可以了,不会出现乱码。唯一缺点就是中文下标不准确,不是递增的

2 .

str:="love 哈哈"
    for _,v:=range str{
        fmt.Printf("%c\n",v)
        // fmt.Println(v)
    }
//怎么都会输出正确的
    for i:=0;i<len(str);i++{
        fmt.Printf("%c\n",str[i])
        // fmt.Println(str[i])
    }

3 .len遍历:按照字节进行遍历,如果有非英文字节,就会出现乱码

4 .切片遍历:先将字符串转为[]rune切片,然后按照常规方式进行遍历

func main(){    
    str:="hello 北京"
    s:=[]rune(str)
    fmt.Println(s)
    for i:=0;i<len(s);i++{
        fmt.Printf("str[%d]=%c",i,s[i])
    }
}
//步长是按照1递增的,没有进行跳跃

字符串截取

1 .索引的起使位置可以通过切片偏移制作

s:="死神来了, 阿斯蒂死神啦啦啦"
    index:=strings.Index(s,",")
    // 返回第一个”,“号的索引
    fmt.Println(index)
    pos:=strings.Index(s[index:],"死神")
//这样直接切割是有问题的
    // 接入第一个”,“号之后的字符串,寻找”死神"在新字符串的位置
    fmt.Println(pos)
    fmt.Println(s[index+pos:])
    // 把两个位置相加,取出最后想要的串



fmt.Println(b)
    // byte表示一个字节

    fmt.Println(c)
    // rune表示四个字节

    fmt.Println(s[:1])
    fmt.Println(string(b[:1]))
    fmt.Println(string(c[:1]))

修改字符串

1 .go无法直接修改每一个字符元素,只能重新构造新的字符串赋值给原来的字符串变量实现

2 .修改字符串的时候,可以将字符串转换为[]byte进行修改

3 .[]byte和string可以通过强制类型互相转换

s1:="helllo"
    s2:=[]byte(s1)
    //将字符串转为byte切片
    for i:=3;i<len(s2);i++{
        s2[i]=' '
    }
    //3-len之间的元素使用空格替换
    fmt.Println(string(s2))
    // 利用string方法将[]byte转为字符串,重新创造一个字符串

字符串拼接

1 .+号:每次加号都会产生一个新的字符串,导致很多临时的,无用的字符串,会给垃圾回收带来很大的压力

2 .高速缓冲实现

var stringBuilder bytes.Buffer
    // 声明一个字节缓冲

    stringBuilder.WriteString("李")
    stringBuilder.WriteString("巴")
    // 向里面添加数据

    fmt.Println(stringBuilder.String())
    // 将缓冲以字符串形式输出

3 .fmt.Sprintf()函数

func main(){
    x := "hello"
    for _, y := range x {
        x=fmt.Sprintf("%s %s",x,string(y))
    }
    fmt.Println(x)
}
1 .格式化样式:字符串形式,如s%,s%
2 .参数列表:多个参数以逗号隔开,个数必须和格式化样式中的个数一一对应
3 .功能:将参数列表中的多个参数以格式化的形式输出
4 .缺点:虽然不会产生临时字符串,但是内部逻辑比较复杂,而且有很多额外的判断,性能也一般

4 .strings.join()函数

func main(){    
    str:=[]string{"a","b","c","d"}
    s:=strings.Join(str,"-")
//用-来连接
    fmt.Println(s)
}
1 .Join会根据字符串数组的内容,计算出一个拼接后的长度,然后申请对应大小的内存,依次将该字符串填入。
2 .该种方式在已有一个数组的前提下,可以提高程序的执行效率,但实际上,原先内存中并没有为拼接之后的字符串所创建好的数组,所以本质上创建这个数据的代价并不小

5 .连接性能比较

1 .较少字符串使用+号
2 .如果拼接的不仅仅是字符串,还有数字之类的其他需求,使用fmt.Sprintf函数
3 .在已有字符串数组的情况下,使用strings.Join
4 .在性能要求高的场景下,使用buffer.WriteString()函数有更好的性能
5 .
str:="love 123 飞机"
    for _,v:=range str{
        // fmt.Printf("%T\n",v)
        // 输出字符的类型

        // fmt.Printf("%v\n",v)
        // 返回本来的值

        // fmt.Printf("%U\n",v)
        // Unicdoe格式

        // fmt.Printf("%#v\n",v)

        // fmt.Printf("%s\n",v)

        // fmt.Printf("%c\n",v)
        // 值对应的unicode值

        // fmt.Printf("%b\n",v)
        // 值对应的二进制

        // fmt.Printf("%t\n",v)
        // 布尔值

        // fmt.Printf("%%\n",v)
        // 百分号

        fmt.Printf("%p\n",v)
    }

utf8,unicode,ascii

1 .Unicdoe,ascii都是一种字符集,为每一个字符分配唯一的id

2 .utf8是一种编码规则,将unicode中的id以某种方式进行编码然后输出

3 .


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK