【9.0】Go语言基础之字符串

发布时间 2023-11-12 12:04:11作者: Chimengmeng

【一】字符编码引入

【二】字符串操作

【1】获取字符串的字节(byte)

(1)英文字符

package main

import "fmt"

func main() {
	// 字符串
	// 【1】单独获取每个字符串的字节 byte
	// 定义字符串
	word := "Hello world!"
	for i := 0; i < len(word); i++ {
		// i 当前循环到的索引值
		fmt.Println("当前循环字符索引 ::>>>> ", i)
		// word[i] 字符串对应的 ASCII 码的值
		fmt.Println("对应字符ASCII 码的值 :>>>> ", word[i])
		// string(word[i]) 将字符串对应的 ASCII 码的值 强转成字符串
		fmt.Println("对应字符的值 :>>>> ", string(word[i]))
		//当前循环字符索引 ::>>>>  0
		//对应字符ASCII 码的值 :>>>>  72
		//对应字符的值 :>>>>  H
	}
}

(2)中文字符出现乱码

package main

import "fmt"

func main() {
	// 字符串
	// 【1】单独获取每个字符串的字节 byte
	// 定义字符串 :中国的中是一个中文,1个中文字符占3个字节
	country := "中国"
	for i := 0; i < len(country); i++ {
		// i 当前循环到的索引值
		fmt.Println("当前循环字符索引 ::>>>> ", i)
		// word[i] 字符串对应的 ASCII 码的值
		fmt.Println("对应字符ASCII 码的值 :>>>> ", country[i])
		// string(word[i]) 将字符串对应的 ASCII 码的值 强转成字符串
		fmt.Println("对应字符的值 :>>>> ", string(country[i])) // 三个字节才能组成一个字符,所以会出现乱码
		//当前循环字符索引 ::>>>>  0
		//对应字符ASCII 码的值 :>>>>  228
		//对应字符的值 :>>>>  ä
	}
}

(3)中文字符乱码解决办法rune

package main

import "fmt"

func main() {
	// 字符串
	// 【1】单独获取每个字符串的字节 byte
	// 定义字符串 :中国的中是一个中文,1个中文字符占3个字节
	country := "中国"

	// 把字符串做成切片
	r := []rune(country) // 强类型转换

	for i := 0; i < len(r); i++ {
		// i 当前循环到的索引值
		fmt.Println("当前循环字符索引 ::>>>> ", i)
		// word[i] 字符串对应的 ASCII 码的值
		fmt.Println("对应字符ASCII 码的值 :>>>> ", r[i])
		// string(word[i]) 将字符串对应的 ASCII 码的值 强转成字符串
		fmt.Println("对应字符的值 :>>>> ", string(r[i])) //
		// 打印字符串的另一种方法
		fmt.Printf("对应字符的值r[i] :>>>> %c \n", r[i])
		//当前循环字符索引 ::>>>>  0
		//对应字符ASCII 码的值 :>>>>  20013
		//对应字符的值 :>>>>  中
		//对应字符的值r[i] :>>>> 中
	}
}

【2】通过字节切片构建字符串

package main

import "fmt"

func main() {
	// 字符串
	// 通过字节切片构建字符串
	byteSliceOne := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}
	byteSliceTwo := []byte{97, 98}
	strOne := string(byteSliceOne)
	strTwo := string(byteSliceTwo)
	fmt.Println("这是构建的字符串strOne :>>>> ", strOne)
	fmt.Println("这是构建的字符串strTwo :>>>> ", strTwo)

	//这是构建的字符串strOne :>>>>  Café
	//这是构建的字符串strTwo :>>>>  ab
}

【3】通过rune构建字符串

package main

import "fmt"

func main() {
	// 字符串
	// 通过rune构建字符串
	runeSlice := []rune{20013, 22269}
	strOne := string(runeSlice)
	fmt.Println("这是构建的字符串strOne :>>>> ", strOne)

	//这是构建的字符串strOne :>>>>  中国
}
  • byte(uint8,一个字节) 和 rune(int32,四个字节)这两种类型,来代表字节和字符

【4】字符串的长度

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	// 字符串
	// 字符串的长度
	word := "China中国"
	// 一个中占 3 个总结,所以有 : 5 + 3 + 3 = 11
	fmt.Println("这是字符word的字节长度 :>>>> ", len(word)) // 这是字符word的字节长度 :>>>>  11
	// 计算字符长度用 utf8.RuneCountInString() : 5 + 1 + 1 = 7
	fmt.Println("这是字符word的字符长度 :>>>> ", utf8.RuneCountInString(word)) // 这是字符word的字符长度 :>>>>  7
}

【5】字符串不可变

package main

import "fmt"

func main() {
	// 字符串
	// 字符串不可变
	word := "China中国"

	// 字符串不能修改值
	// word[0]="W" // Cannot assign to word[0]
	// word[0]='w' // Cannot assign to word[0]

	// 字符串可以根据索引取值
	fmt.Println("根据索引取值word[0] :>>>> ", word[0])         // 根据索引取值word[0] :>>>>  67
	fmt.Println("根据索引取值word[0] :>>>> ", string(word[0])) // 根据索引取值word[0] :>>>>  C

	// 字符串不能修改值,但是切片可以修改值
	// 转成 rune 的切片 --- 切片占内存 --- 修改切片不会影响原来的字符串
	r := []rune(word)
	r[0] = 'S'
	fmt.Println("这是切片修改后的word :>>>> ", word)
	fmt.Println("这是切片修改后的r :>>>> ", r)
	fmt.Println("这是切片修改后的r :>>>> ", string(r))
	//这是切片修改后的word :>>>>  China中国
	//这是切片修改后的r :>>>>  [83 104 105 110 97 20013 22269]
	//这是切片修改后的r :>>>>  Shina中国
}