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]))
}

  

 

posted @   专职  阅读(470)  评论(1编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示