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

  

 

posted @ 2021-10-06 13:58  专职  阅读(446)  评论(1编辑  收藏  举报