🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] go语言的string是一种数据类型。这个数据类型占用16字节空间,前面8字节是一个指针,指向字符串的地址。后面八个字节是一个整数,标识字符串长度 ## 字符串的存储原理 ![](https://img.kancloud.cn/d3/ac/d3ac0bff3fd68c459dd266fe7b8297b0_1125x475.png) string 数据结构,源码包 `src/runtime/string.go:stringStruct` 定义了string的数据结构: ```go type stringStruct struct { str unsafe.Pointer len int } ``` >[info] > - stringStruct.str:字符串的首地址 > - stringStruct.len: 字符串的长度 ## Unicode 转换 utf8 ```go var s rune s = '曾' fmt.Printf("字符'曾'对应的Unicode的十进制: %d\n", s) fmt.Printf("字符'曾'对应的Unicode的十六进制: %x\n", s) fmt.Printf("字符'曾'对应的Unicode的二进制: %b\n", s) // 运行结果: // 字符'曾'对应的Unicode的十进制: 26366 // 字符'曾'对应的Unicode的十六进制: 66fe // 字符'曾'对应的Unicode的二进制: 110011011111110 ``` Unicode二进制转换utf8二进制规则:`1110xxxx 10xxxxxx 10xxxxxx` 将Unicode最后六位补上utf8第三个字符的xxxxxx。将Unicode倒数7到12个字符补上utf第二个字符的xxxxxx。将Unicode剩下的数字补上utf8第一个字符(不够前面补0) 示例如下: '曾'对应的Unicode二进制:110011011111110 '曾'对应的utf8二进制:11100110 10011011 10111110 验证 ```go s1 := "曾" for i := 0; i < len(s1); i++ { fmt.Printf("s1[%d]: %d, %b\n", i, s1[i], s1[i]) } // 运行结果: // s1[0]: 230, 11100110 // s1[1]: 155, 10011011 // s1[2]: 190, 10111110 ``` ## 字符串与字节串相互转换 ```go // 字符串与字节串相互转换 // (1) 字符串转字节串,有两种方式转换方式。 s4 := "abc,您好" fmt.Println([]byte(s4)) // utf8 编码 【常用】 fmt.Println([]rune(s4)) // Unicode 编码 // (2) 字节串转字符串 b1 := []byte{97, 98, 99, 44, 230, 130, 168, 229, 165, 189} b2 := []rune{97, 98, 99, 44, 24744, 22909} fmt.Println(string(b1)) fmt.Println(string(b2)) // 运行结果: // [97 98 99 44 230 130 168 229 165 189] // [97 98 99 44 24744 22909] // abc,您好 // abc,您好 ``` ## 统计字符串个数 ```go s5 := "abc,您好" fmt.Printf("len: %v\n", len([]rune(s5))) // 运行结果: // len: 6 ``` ## for遍历字符串 ```go s3 := "您好呀!abc" for i, v := range s3 { fmt.Println(i, string(v)) } // 运行结果: // 0 您 // 3 好 // 6 呀 // 9 ! // 12 a // 13 b // 14 c ```