string

aside section ._1OhGeD · · 981 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

基础

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 .


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:string

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

981 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传