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

站长

不具版权性
不具时效性

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


目录

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

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

bpple


一切顺利

fetain

fetain


good luck

bx

bx


good luck

热门文章

Emoji收集

2024-11-01

542
Hello Halo

2024-10-30

524
本地部署LLM

2024-08-22

505
Uptime Kuma

2024-11-29

499
229

访问统计