Go-Rune

文章摘要

Bpple-GPT

Go-Rune问题研究


这个问题是当时在测试range的时候写的一个示例:

 package main
 ​
 import "fmt"
 ​
 func main() {
     Chinese_str := "中华民族万岁"
     fmt.Print(Chinese_str)
     for i, v := range Chinese_str {
         fmt.Print(i, Chinese_str[v-1], " ")
     }
 }
 ​

但是输出结果却是

 G:\go\awesomeProject\Range
 go run Chinese_Example.go
 中华民族万岁panic: runtime error: index out of range [20012] with length 18
 ​
 goroutine 1 [running]:
 main.main()
         G:/go/awesomeProject/Range/Chinese_Example.go:9 +0x166
 exit status 2

问题在于

  • **在 **Chinese_str[v-1] 中,v 是 rune 类型(Unicode 码点),而不是索引

这里了解一下rune

rune 是 Go 语言中的一种基本数据类型,它是 int32 的别名,用于表示一个 Unicode 码点(code point)。一个 rune 字面量就是一个单引号括起来的字符。

  • **直接使用 **Chinese_str[index] 会得到字节(byte),而不是完整的中文字符
  • 中文字符在 UTF-8 编码中占用 3 个字节,不能直接按字节索引访问

rune类型

rune 的重要特性:

  1. 大小固定
    • rune 总是 4 字节(32位)
    • 可以表示任何 Unicode 字符
  2. 用途
    • 处理 Unicode 字符
    • 支持多语言字符(中文、日文、emoji等)
    • 字符串遍历和操作
 package main
 ​
 import "fmt"
 ​
 func main() {
     var zhong rune = '中'
     //fmt.Println(zhong)
     //字符
     fmt.Printf("%c\n", zhong)
     //Unicode
     fmt.Printf("%d\n", zhong)
     //16进制
     fmt.Printf("%x\n", zhong)
 ​
 }

---》

 G:\go\awesomeProject\data_structure\rune
 go run rune1.go
 20013
 中
 20013
 4e2d

解决方法

  • Go 语言中的字符串是以 UTF-8 编码存储的
 package main
 ​
 import "fmt"
 ​
 func main() {
     Chinese_str := "中华民族万岁"
     fmt.Println(Chinese_str)
     
     // 使用 range 遍历字符串
     for i, v := range Chinese_str {
         fmt.Printf("索引:%d 字符:%c Unicode:%d\n", i, v, v)
     }
 }

但是输出结果如下:

 G:\go\awesomeProject\data_structure\rune
 go run rune2.go
 中华民族万岁
 索引:0 字符:中 Unicode:20013
 索引:3 字符:华 Unicode:21326
 索引:6 字符:民 Unicode:27665
 索引:9 字符:族 Unicode:26063
 索引:12 字符:万 Unicode:19975
 索引:15 字符:岁 Unicode:2368

索引是三的倍数是由于: 因为每个中文字符在 UTF-8 编码中占用 3 个字节,i 表示字节偏移量,而不是字符位置

为了解决这个问题,我们可以转换成rune切片

 package main
 ​
 import "fmt"
 ​
 func main() {
     Chinese_str := "中华民族万岁"
     // 转换为 rune 切片
     runes := []rune(Chinese_str)
 ​
     for i, v := range runes {
         fmt.Printf("位置:%d 字符:%c\n", i, v)
     }
 }
 //    fmt.Printf("字节长度:%d\n", len(Chinese_str))            输出字节长度
 //    fmt.Printf("字符数量:%d\n", len([]rune(Chinese_str)))    输出字符数量

结果如下:

 G:\go\awesomeProject\data_structure\rune
 go run rune3.go
 位置:0 字符:中
 位置:1 字符:华
 位置:2 字符:民
 位置:3 字符:族
 位置:4 字符:万
 位置:5 字符:岁

others

牢记一个-->"Go语言默认使用 UTF-8 编码,这是 Go 语言的一个重要特性"

下面是一个记录📝

 func main() {
     const π = 3.14159
     fmt.Println(π)
     str := "👋 Hello 中国🀄️ 🌍"
     fmt.Println(str) // 输出:苹果
 }
 ​

不知道这样行不行

 package main
 ​
 import "fmt"
 ​
 func main() {
     // emoji 作为变量名
     var 😀 = "笑脸"
     var 🍎 = "苹果"
     
     fmt.Println(😀) // 输出:笑脸
     fmt.Println(🍎) // 输出:苹果
     
     // 甚至可以用作函数名
     fmt.Println(say👋("世界")) // 输出:你好,世界
 }
 ​
 func say👋(name string) string {
     return "你好," + name
 }

但是我没有跑通

还发现了Unicode库检测,挺好玩的

 package main
 ​
 import (
     "fmt"
     "unicode"
 )
 ​
 func main() {
     //Uniocde库使用
     var str rune = '中'
     fmt.Println("是否为汉字?", unicode.Is(unicode.Han, str))
 ​
     fmt.Println(string((unicode.ToLower('A'))))
 }

用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

BX33661

isfp 探险家

站长

不具版权性
不具时效性

文章内容不具时效性。若文章内容有错误之处,请您批评指正。


目录

欢迎来到Bpple的站点,为您导航全站动态

65 文章数
20 分类数
44 评论数
15标签数
最近评论
bpple

bpple


一切顺利

fetain

fetain


good luck

bx

bx


good luck

热门文章

Emoji收集

2024-11-01

551
Hello Halo

2024-10-30

532
本地部署LLM

2024-08-22

511
Uptime Kuma

2024-11-29

507
241

访问统计