golang中字符串的底层实现原理和常见功能
1. 字符串的底层实现原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 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个功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 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. 字符串索引切片和循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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])) } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· spring官宣接入deepseek,真的太香了~