golang中字符串的底层实现原理和常见功能
1. 字符串的底层实现原理
package main import ( "fmt" "strconv" "unicode/utf8" ) func main() { // 计算机中所有的操作和数据最终都是二进制 // go语言中的字符串是utf-8编码的序列 // 字符串本质上是utf-8编码的序列 name := "马馨彤" // 马 => 11101001 10101001 10101100 fmt.Println(name[0], strconv.FormatInt(int64(name[0]), 2)) fmt.Println(name[1], strconv.FormatInt(int64(name[1]), 2)) fmt.Println(name[2], strconv.FormatInt(int64(name[2]), 2)) // 馨 => 11101001 10100110 10101000 fmt.Println(name[3], strconv.FormatInt(int64(name[3]), 2)) fmt.Println(name[4], strconv.FormatInt(int64(name[4]), 2)) fmt.Println(name[5], strconv.FormatInt(int64(name[5]), 2)) // 彤 => 11100101 10111101 10100100 fmt.Println(name[6], strconv.FormatInt(int64(name[6]), 2)) fmt.Println(name[7], strconv.FormatInt(int64(name[7]), 2)) fmt.Println(name[8], strconv.FormatInt(int64(name[8]), 2)) // 2. 获取字符串的长度=9,utf-8编码的字节长度 fmt.Println(len(name)) // len获取的是字节长度 // 3. 字符串转换为一个字节的切片 byteSets := []byte(name) // [233 169 172 233 166 168 229 189 164] fmt.Println(byteSets) // 4. 字节的切片转换为字符串 byteList := []byte{233, 169, 172, 233, 166, 168, 229, 189, 164} targetString := string(byteList) fmt.Println(targetString) // 5. 将一个字符串转换为 unicode字符集码点的切片 (rune) 9a6c => 马 99a8 => 馨 5f64 => 彤 // rune使用的是unicode中的ucs4 byteRune := []rune(name) fmt.Println(byteRune) // [39532 39336 24420] fmt.Println(byteRune[0], strconv.FormatInt(int64(byteRune[0]), 16)) fmt.Println(byteRune[1], strconv.FormatInt(int64(byteRune[1]), 16)) fmt.Println(byteRune[2], strconv.FormatInt(int64(byteRune[2]), 16)) // rune切片转换为字符串 runeList := []rune{39532, 39336, 24420} target2String := string(runeList) fmt.Println(string(target2String)) // 字符长度 runeLength := utf8.RuneCountInString(name) // 根据字符串统计字符长度 two := utf8.RuneCount(byteList) // 根据字节切片统计字符长度 fmt.Println(runeLength) fmt.Println(two) }
2. 常见15个功能
package main import ( "fmt" "reflect" "strconv" "strings" "unicode/utf8" ) func main() { var name = "武沛齐" var name2 = "WuPeiQi" var name3 = " wupeiqiqi " var name4 = "抬老子的意大利的炮来" // 1. 获取字符串的长度 fmt.Println(len(name)) // 字节长度 fmt.Println(utf8.RuneCountInString(name)) // 字符长度 // 2. 是否以xx开头 ret1 := strings.HasPrefix(name, "武") fmt.Println(ret1) // 3. 是否以xx结尾 ret2 := strings.HasSuffix(name, "齐") fmt.Println(ret2) // 4. 是否包含 ret3 := strings.Contains(name, "沛") fmt.Println(ret3) // 5. 变大写 ret4 := strings.ToUpper(name2) fmt.Println(ret4) // 5. 变小写 ret5 := strings.ToLower(name2) fmt.Println(ret5) // 6. 去两边 ret6 := strings.Trim(name3, " ") ret7 := strings.TrimLeft(name3, " ") ret8 := strings.TrimRight(name3, " ") fmt.Println(ret6, ret7, ret8) // 7. 替换,第三个参数代表从左到右替换1、2和所有 ret9 := strings.Replace(name3, "i", "I", 1) ret10 := strings.Replace(name3, "i", "I", 2) ret11 := strings.Replace(name3, "i", "I", -1) fmt.Println(ret9, ret10, ret11) // 8. 分割 ret12 := strings.Split(name4, "的") fmt.Println(ret12) // 9. 拼接1,不建议 message := "我爱" + "北京天安门" fmt.Println(message) // 10 拼接2,建议 效果高一些 dataSlice := []string{"我爱", "北京天安门"} ret13 := strings.Join(dataSlice, "-") fmt.Println(ret13) // 效率更高一些 go1.10之后 var builder strings.Builder builder.WriteString("我爱-") builder.WriteString("北京天安门") value := builder.String() fmt.Println(value) // 11. string 转换为 int类型 num1 := "123465" ret14, _ := strconv.Atoi(num1) // 方法1 结果是int类型 fmt.Println(ret14, reflect.TypeOf(ret14)) ret15, _ := strconv.ParseInt(num1, 10, 0) // 结果是int64类型 fmt.Println(ret15, reflect.TypeOf(ret15)) // 12. int 转换为 string num2 := 789 ret16 := strconv.Itoa(num2) fmt.Println(ret16, reflect.TypeOf(ret16)) ret17 := strconv.FormatInt(int64(num2), 10) fmt.Println(ret17, reflect.TypeOf(ret17)) // 13. 字符串和字节切片 byteSlice := []byte(name) // 字符串转字节 fmt.Println(byteSlice) // [230 173 166 230 178 155 233 189 144] // 字节转字符串 targetString := string(byteSlice) fmt.Println(targetString) // 14. 字符串和rune切片 runeSlice := []rune(name) // 字符串转rune切片 fmt.Println(runeSlice) // rune切片转字符串 targetString2 := string(runeSlice) fmt.Println(targetString2) // 15. string 和 字符 // 根据码点找到对应的字符信息 v1 := string(65) // 数字转字符 fmt.Println(v1, reflect.TypeOf(v1)) // A string // 字符串转rune数字和字节长度 v2, size := utf8.DecodeRuneInString("武") fmt.Println(v2, size) // 应用场景:生成一个随机数,然后调用string得到一个随机字符 }
3. 字符串索引切片和循环
package main import "fmt" func main() { var name = "a武沛齐" // 1. 索引获取字节 ret1 := name[0] fmt.Println(ret1) // 2. 切片获取字节区间 ret2 := name[:3] fmt.Println(ret2) // 3. 手动循环获取所有字节 for i := 0; i < len(name); i++ { fmt.Println(i, name[i]) } // 4. for range 循环获取所有字符 for index, item := range name { fmt.Println(index, item, string(item)) } // 5. 转换成rune切片 runeSlice := []rune(name) fmt.Println(runeSlice) // [97 27494 27803 40784] fmt.Println(runeSlice[0], string(runeSlice[0])) fmt.Println(runeSlice[1], string(runeSlice[1])) }