字符串的概念
-
一个字符串是一个不可改变的字节序列
字符串属于的类型
-
字符串是一种值类型,且值不可变,创建某个文本后将无法再次修改这个文本的内容
-
字符串是字节的定长数组。
但是数组是引用类型的
定义字符串
符号:
""
-
u 或 U:Unicode 字符
-
:反斜杠自身
一般的比较运算符(==、!=、<、<=、>=、>)是通过在内存中按字节比较来实现字符串比较的,比较的结果是字符串自然编码的顺序。
字符串所占的字节长度可以通过函数 len() 来获取,例如 len(str)。
字符串的内容(纯字节)可以通过标准索引法来获取,在方括号[ ]
内写入索引,索引从 0 开始计数:
-
字符串 str 的第 1 个字节:str[0]
-
第 i 个字节:str[i - 1]
-
最后 1 个字节:str[len(str)-1]
-
获取字符串中某个字节的地址属于非法行为,例如 &str[i]。
字符串拼接符"+"、"+="
示例:
package main
import "fmt"
func main() {
s1 := "Hel" + "lo"
s1 += "World"
fmt.Println(s1)
}
Go语言中字符串的内部实现使用 UTF-8 编码
定义多行字符串
特点:
-
Go语言中,双引号写字符串的方式是字符串字面量(string literal)。不支持跨行
-
在源码中嵌入多行字符串要使用"`"反引号--->多用于内嵌源码
-
两个反引号间的字符串将被原样赋值到变量中。
多行字符串重反引号间换行将被作为字符串中的换行,所有的转义字符均无效,文本将会原样输出。
package main
import "fmt"
func main() {
const value = `
第一行
第二行
第三行
`
fmt.Println(value)
}
截取字符串当中的某串子串
将字符串中的某一段字符称做子串(substring)
package main
import (
"fmt"
"strings"
)
func main() {
subString := "同学起立,老师上课。"
//截取出来的字符串
subStringNo1 := strings.Index(subString, ",") //这只是截取出来了字符串里
subStringNo2 := strings.Index(subString[subStringNo1:], "人类")
fmt.Println(subStringNo1, subStringNo2, subString[subStringNo1+subStringNo2:])
}
代码说明:
-
在
subString
的字符串中搜索中文的逗号,返回的位置存在subStringNo1
变量中,类型是 int--->从subString
字符串开始的 ASCII 码位置。-
strings.Index()
函数并没有像其他语言一样,提供一个从某偏移开始搜索的功能。
-
找到指定符号的字符索引位置
-
subString[subStringNo1:]
从subString
的subStringNo1
位置开始到subString
字符串的结尾构造一个子字符串,返回给string.Index()
进行再索引。-
得到的
subStringNo2
是相对于subString[subStringNo1:]
的结果。
-
总结
字符串索引比较常用的有如下几种方法:
-
strings.Index
:正向搜索子字符串。 -
strings.LastIndex
:反向搜索子字符串。 -
搜索的起始位置可以通过切片偏移制作。
strings
包下的方法都没有进行偏移
字符串拼接
Go 语言中也有类似于StringBuilder
的机制来进行高效的字符串连接。在Go中缓冲字节流的本质是一个变量
package main
import (
"bytes"
"fmt"
"strings"
)
func main() {
hammer := "锤哥"
//声明字符缓冲变量
stringBuilder := bytes.Buffer{}
//把字符串写进来
stringBuilder.WriteString(hammer) //字符串转变成了二进制形式
fmt.Println(stringBuilder)
//将缓冲以字符串的形式输出
fmt.Println(stringBuilder.String())
}
bytes.Buffer 是可以缓冲并可以往里面写入各种字节数组的。字符串也是一种字节数组,使用 WriteString() 方法进行写入。
调用 WriteString() 方法,写入 stringBuilder 中,然后再通过 stringBuilder.String() 方法将缓冲转换为字符串。
fmt.Sprintf(格式化输出)
声明格式:
fmt.Sprintf(格式化样式, 参数列表…)
-
格式化样式:字符串形式,格式化动词以
%
开头。 -
参数列表:多个参数以逗号分隔,个数必须与格式化样式中的个数一一对应,否则运行时会报错。
示例:
package main
import "fmt"
func main() {
number := 8
name := "Jun"
fmt.Printf("带噶后,我今年%d岁了,我叫%s", number, name)
pi := 3.14159
// 按数值本身的格式输出
variant := fmt.Sprintf("%v %v %v", "月球基地", pi, true)
fmt.Println(variant)
// 匿名结构体声明, 并赋予初值
profile := &struct {
Name string
HP int
}{
Name: "rat",
HP: 150,
}
fmt.Printf("使用'%%+v' %+v
", profile)
fmt.Printf("使用'%%#v' %#v
", profile)
fmt.Printf("使用'%%T' %T
", profile)
/*
C语言中, 使用%d代表整型参数
*/
}
参考: