Golang数据类型(字符串)
- 手机
- 2025-07-21 19:20:16

字符串重要概念 根据Go语言官方的定义: In Go, a string is in effect a read-only slice of bytes. 意思是Go中的字符串是一组只读的字节切片(slice of bytes),每个字符串都使用一个或多个字节表示(当字符为 ASCII 码表上的字符时占用 1 个字节,比如英文字母,其它字符根据需要占用 2-4 个字节,比如汉语、日语中的汉字、平假名、片假名等)。 Go中的字符串使用的是UTF-8编码Go中的纯英文字符串的字节切片长度和它的字母个数完全相等,比如test这个英文单词有4个字母,那么,len("test")返回的值也为4 因为英文字母的编码为ASCII,可以用字节表示。 而其他需要用Unicode编码的语言,比如中文字符串,那么它的字节切片长度往往不会等于它的文字个数,比如"测试"这个词语虽然只包含两个汉字,但是len("测试")会返回6,因为"测"字和"试"字分别需要用3个字节来表示,总共占用6个字节
[c-alert type=“info”]那就有一个疑问了,怎么样才能让中文按字数显示长度呢?[/c-alert]
使用golang中的Rune切片(Rune Slice) 点击查看
Go语言中声明一个字符串变量只能用双引号""或者反勾号(backtick,‘’) 在Go中单引号只能用来声明单一字符(character),即rune。字符串格式化 Go语言也支持字符串格式化
format()函数以及f-strings三种方式来做字符串格式化,字符串格式化在Go中的的形式较为单一,我们可以通过fmt.Printf()配合取模运算符%来实现字符串格式化,举例如下:
var string1 string = "我是字符串1" var int_value int = 100 var string2 string = "我是字符串2" var float_value1 float64 = 3.14 fmt.Printf("%s %d\n", string1, int_value) fmt.Printf("%s %f\n", string2, float_value1)
在Go中使用取模运算符来做字符串格式化时,常见的格式码(format code)如下:
格式化输出的各种格式 %v: 通用格式,将变量的默认格式输出。%T: 变量的类型。%d: 十进制整数。%b: 二进制表示的整数。%o: 八进制表示的整数。%x: 十六进制表示的整数,使用小写字母。%X: 十六进制表示的整数,使用大写字母。%s: 字符串。%q: 带有双引号的字符串。%f: 浮点数,默认精度。%e,%E: 科学计数法表示的浮点数,%e 使用小写字母,%E 使用大写字母。%g,%G: 根据实际情况选择 %e 或 %f 以产生更紧凑的(无末尾的零)输出,%g 使用小写字母,%G 使用大写字母。%t: 布尔值,true 或 false。%p: 指针,以十六进制表示。%%: 百分号本身。 其实有两种输出供我们选择 第一种,直接输出 username := "linrux" age := 18 address := "beijing" mobile := "123456777" fmt.Printf("用户名:%s, 年龄:%d, 地址:%s, 电话:%s\r\n", username, age, address, mobile)</code></pre>输出:
这种方式使用 %s、%d 等格式化占位符,通过 Printf 函数直接输出格式化后的字符串。
第二种,拼接后再输出 username := "linrux" age := 18 address := "beijing" mobile := "123456777"msg := fmt.Sprintf(“用户名:%s, 年龄:%d, 地址:%s, 电话:%s\r\n”, username, age, address, mobile) fmt.Println(msg) 输出:
这种方式使用 Sprintf 函数将格式化后的字符串保存在一个变量中,然后通过 Println 函数打印这个变量。
字符串的拼接 Go语言中做字符串拼接的方式很多,主要有字符串拼接符“+”、strings.Join()、bytes.Buffer、strings.Builder等四种形式来实现字符串的拼接(从严格意义上来说,上面讲到的字符串格式化也属于字符串拼接的一种),下面一一举例讲解它们的使用方法及区别: 字符串拼接符“+” 字符串拼接符“+”是最常见也是最为简单的字符串拼接方式,在Go用“+”号做拼接前需要确保做拼接的变量的数据类型为字符串,如果不是字符串,则必须用fmt.Sprint()将其转换成字符串才能完成拼接,否则系统会返回"mismatched types string and int"的异常,如下: func main() { var string1 string = "我是字符串1" var int_value int = 100 var string2 string = "我是字符串2" var float_value1 float64 = 3.14 fmt.Printf(string1 + int_value) fmt.Printf(string2 + float_value1) //fmt.Printf("%s %f\n", string2, float_value1) }
输出:
变量int_value和float_value1因为不是字符类型,所以无法连接字符串,解决方法是将变量的类型转换成字符串
func main() { var string1 string = "我是字符串1" var int_value int = 100 var string2 string = "我是字符串2" var float_value1 float64 = 3.14 fmt.Printf(string1 + fmt.Sprint(int_value) + "\n") fmt.Printf(string2 + fmt.Sprint(float_value1)) //fmt.Printf("%s %f\n", string2, float_value1) }输出:
strings.Join()、切片、数组 在Go中,字符串实际上是一组只读、长度可变的字节切片。要知道strings.Join()的用法,必须知道什么是切片(Slice),而要理解切片,又必须先要知道什么是数组(Array),所谓数组可以理解为一种特殊的列表,区别是列表可以包含多种数据类型的元素,而数组只能包含同一种数据类型的元素,即一个数组里的所有元素必须全部为字符串,或者全部为整数
在Go中,切片是数组衍生出来的概念,两者的区别是:数组的长度是固定的,在声明一个数组时,你必须指定该数组的长度(即该数组里面有多少个元素),以及该数组里元素的数据类型。而切片不同,切片的长度不是固定的,在声明一个切片时,只需指明切片里元素的数据类型即可,这里简单举例说明两者的却别:
func main() { vendor1 := [5]string{"C", "i", "s", "c", "o"} vendor2 := []string{"H", "u", "a", "w", "e", "i"} fmt.Printf("%T\n", vendor1) fmt.Printf("%T\n", vendor2) }输出:
对于切片更加详细的说明,在这里已经说
虽然切片是在数组的基础上衍生出来的数据类型,但因为切片的灵活性,实际上它在Go中的应用比数组更广泛,比如strings.Join()就必须配合切片来完成字符串的拼接,举例如下:
func main() { var vendor1 []string = []string{"C", "i", "s", "c", "o"} var vendor2 []string = []string{"H", "u", "a", "w", "e", "i"} result1 := strings.Join(vendor1, "") result2 := strings.Join(vendor2, "") fmt.Println(result1) fmt.Println(result2) }输出:
注意strings.Join(vendor1, “”)后面的""表示分隔符,这里分隔符为空,表示等下做拼接时,切片里的所有字符串元素将紧贴在一起
可以换成其他的分隔符试一下
func main() { var vendor1 []string = []string{"C", "i", "s", "c", "o"} var vendor2 []string = []string{"H", "u", "a", "w", "e", "i"} result1 := strings.Join(vendor1, ",") result2 := strings.Join(vendor2, ",") fmt.Println(result1) fmt.Println(result2) }输出:
bytes.Buffer 因为在Go中字符串实际上是一组只读、长度可变的字节切片,因此我们还可以引入Go内置的bytes标准包,通过它创建一个类型为bytes.Buffer的变量(你可以把bytes.Buffer变量理解为组成字符串的字节),然后使用它的WriteString()方法来做拼接,最后通过该变量的String()方法将它转化为字符串,即得到了拼接后的字符串内容,举例如下: func main() { var vendor1 bytes.Buffer vendor1.WriteString("l") vendor1.WriteString("i") vendor1.WriteString("n") vendor1.WriteString("r") vendor1.WriteString("u") vendor1.WriteString("x") var vendor2 bytes.Buffer vendor2.WriteString("h") vendor2.WriteString("e") vendor2.WriteString("l") vendor2.WriteString("l") vendor2.WriteString("o") fmt.Println(vendor1.String()) fmt.Println(vendor2.String()) } 输出:
这里我们通过import bytes导入了bytes这个标准包,然后创建了vendor1和vendor2两个类型为bytes.Buffer的变量,我们通过bytes.Buffer自带的WriteString()方法将字母做了拼接
注意使用bytes.Buffer来做字符串拼接可以避免生成一个新的字符串变量(比如前面讲strings.Join()时,我们额外创建了result1和result2两个变量),所有拼接的操作都是在同一个变量上完成的。
strings.Builder 上面讲到的bytes.Buffer()是通过bytes这个模块来操作字符串的拼接,这种方法多少让用户感到有些迷惑。从go1.10开始,Go语言官方在strings这个标准包里新加入了strings.Builder这个数据类型,并且官方鼓励用户在做字符串的拼接时使用strings.Builder,做字节的拼接时使用bytes.Buffer。 func main() { var vendor1 strings.Builder vendor1.WriteString("l") vendor1.WriteString("i") vendor1.WriteString("n") vendor1.WriteString("r") vendor1.WriteString("u") vendor1.WriteString("x") var vendor2 strings.Builder vendor2.WriteString("h") vendor2.WriteString("e") vendor2.WriteString("l") vendor2.WriteString("l") vendor2.WriteString("o") fmt.Println(vendor1.String()) fmt.Println(vendor2.String()) } 输出:
可以看到,strings.Builder和bytes.Buffer的使用方法几乎一模一样,两者都是通过WriteString()来做字符串的拼接,都是通过String()来获得拼接后的字符串。不过根据Go官方的说法strings.Builder在内存使用上的性能要略优于bytes.Buffer,这里推荐大家按照官方的建议,在做字符串的拼接时使用strings.Builder,做字节的拼接时使用bytes.Buffer。
字符串的索引 在开发的过程中,有时我们需要获取字符串中的某个或者某段字符,这时就需要对字符串做索引(针对单个字符)或者切片(针对多个连续字符)。Go语言的字符串索引号从0开始,即字符串里从左往右的第一个字符的索引号为0
在Go中,索引返回的值为byte(byte是uint8的别名,uint8的中文叫做无符号8位整数,相关的知识会在下一篇讲解整数的章节中讲到),如果你用fmt.Println(vendor1[0])会打印出字母C对应的uint8的值
func main() { vendor1 := "Linrux" fmt.Println(vendor1[0]) }
解决办法有两个:
1.使用%c格式码(%c格式码表示character,即字符,注意字符不等同于字符串),通过字符串格式化的方式将uint8整数转化为字符:
func main() { vendor1 := "Linrux" fmt.Printf("%c", vendor1[0]) }输出:
2.使用string()函数将unit8整数转化为字符串:
func main() { vendor1 := "Linrux" fmt.Println(string(vendor1[0])) }输出:
PS:在Go中,索引号不支持使用负整数,只能使用0或正整数,否则系统会返回“invalid string index -1 (index must be non-negative)”的异常,举例如下:
func main() { vendor1 := "Linrux" fmt.Println(string(vendor1[-1])) }输出:
解决的方法是使用len()函数:
func main() { vendor1 := "Linrux" fmt.Println(string(vendor1[len(vendor1)-1])) }输出:
字符串的不可变性 作为一组字节的切片,Go语言中的字符串具有不可变性(immutability),一旦创建了一个字符串变量后,我们无法对它的内容做任何修改,哪怕一个字符,举例如下: func main() { vendor1 := "Linrux" vendor1[0] = "s" fmt.Println(vendor1) } 输出:
Golang数据类型(字符串)由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Golang数据类型(字符串)”
下一篇
计数问题(数位DP)