1. rune类型 rune类型是Go语言中的一个基本类型,其实就是一个uint32的别名,主要用于表示一个字符类型大于一个字节小于等于4个字节的情况下,特别是中文字符,定义如下所示: rune is type rune = int32 备注:摘自https://golang.org/pkg/builtin/#rune 备注:一个中文字符由三个字节才能表示,所以rune对于字符串是中文字符的情况下,支持比较好 对于英文字符串,不管是用rune类型还是byte类型,不管是字符串的长度还是取值,都是相同的。 2).对于中文字符来说,rune类型的操作就比byte类型的操作更加友好很多,我们可以通过[:]操作直接取出中文的对应数量,而byte取出来却是乱码??。 ----
今天看golang代码看到一个单词 rune ,熟悉而陌生。之前学习go并没有过多注意这个“神秘符号”。 rune在golang中是int32的别名,在各个方面都与int32相同。 做几个小测试 s:="hello你好" fmt.Println(len(s))//输出长度为11 fmt.Println(len([]rune(s)))//输出长度为7 s="你好" fmt.Println(len(s))//输出长度为6 fmt.Println(len([]rune(s)))//输出长度为2 s="你" fmt.Println ([]byte(s))//输出长度为6 fmt.Println(rune('你'))//输出20320 通过上述代码可以将rune理解为 一个 可以表示unicode 编码的值int 的值,称为码点 只不过go语言把这个码点抽象为rune。 想深入了解 可以点击 https://blog.golang.org/strings。
但不能用来引用多行) 反引号用来创建原生的字符串字面量,这些字符串可能由多行组成(不支持任何转义序列),原生的字符串字面量多用于书写多行消息、HTML以及正则表达式 而单引号则用于表示Golang的一个特殊类型:rune 一个rune对应一个UTF-8字符,所以一个中文字符对应一个rune,如果要按下标访问中文,则必须要转换成为rune才行。 值得注意的是,len()方法获取的字节数而不是字符个数,要获取包含中文的的字符个数,也是要转换成为rune才行。
Go语言中byte和rune实质上就是uint8和int32类型。byte用来强调数据是raw data,而不是数字;而rune用来表示Unicode的code point。 the set of all signed 32-bit integers (-2147483648 to 2147483647) byte alias for uint8 rune ) []rune { return r } func main() { b := []byte{0, 1} u8 := []uint8{2, 3} fmt.Printf ("%T %T \n", b, u8) fmt.Println(byteSlice(b)) fmt.Println(byteSlice(u8)) r := []rune{4, rune out int }{ //string用反引号能换行, 但不支持转义, rune是一个uint32,即一个unicode字符 {`as
一段简单的代码执行后报错more than one character in rune literal 错误原因 因为错误使用引号,把单引号修改为双引号问题解决!
string uint8 uint8 uint8 uint8 int32 a a abc uint8 int32 我 æ 我 uint8 int32 i i i a 分析: 原来是 byte 表示一个字节,rune 正确做法: fmt.Println(string([]rune(s)[:3])) 截取中 总结 : 1. for range 时会把 string[i]进行强制转换为 rune, 如果我们只需要byte,就多此一举了. 2. 默认按rune处理是非常稳妥的方式,不会有乱码。 3. string默认按[]byte进行解析,对含非ascii string的slice操作会产生乱码,需要转成rune.
不了解rune类型 本文讨论rune相关知识,在深入讨论前,我们需要理解字符和编码的区别: 一个字符,正如其名,表示字符集合中的一个元素,例如,Unicode字符集包含2^21个字符 编码是将字符表用二进制来表示 理解这些非常重要,因为在Go语言中,1个rune字符是一个代码点。 此外,我们知道UTF-8编码会将一个字符编码为1到4个字节,4字节也就是32比特。 所以在Go语言中,rune被定义为int32的别名。 type rune = int32 还有一点需要强调,有些人认为Go字符串都是UTF-8, 事实并不是这样。 但是从文件系统中读取到的字符串不一定是UTF-8编码 rune对应一个Unicode中的码点,每个Unicode字符表示为单个rune值 采用UTF-8编码,Unicode字符集被编码为1到4个字节 Go
为此,Go在代码中引入了一个新术语,称为 rune。 rune是int32的类型别名: // rune is an alias for int32 and is equivalent to int32 in all ways. 类型,rune类型为int32,所以占4个字节。 ) // [103 111 76 97 110 103] } []rune()将字符串转换为rune切片 []byte()将字符串转换为byte切片 由于都是Ascii码字符串,所以输出的整数都一致 7.总结 Go 语言中的字符串是一个只读的字节切片 声明的任何单个字符,go语言都会视其为rune类型 []rune()可以把字符串转换为一个rune数组(即unicode数组) 一个rune就表示一个
代表 Unicode 码点的字节序列称为 rune。 在 Go 中不会保证字符串中的字符被规范化。 Go 语言将单词 rune 定义为类型 int32 的别名,因此当整数值表示码点时,程序会很清晰。此外,你可能会认为是字符常量的常量在 Go 中称为 rune 常量。 代表 Unicode 码点的字节序列称为 rune。 在 Go 中不会保证字符串中的字符被规范化。 相比之下, range 循环在每次迭代中会解码一个 UTF-8 编码 rune。每次循环时,循环的索引都是当前 rune 的起始位置 (以字节为单位),码点是其值。 该函数的返回值是 rune 及其宽度 (以 UTF-8 编码的字节)。
rune is letter rune is lower case rune is printable rune For '̀': is graphic rune is mark rune is printable rune For '9': is digit rune is graphic rune is number rune is printable rune For '! : is graphic rune is printable rune is punct rune For ' ': is graphic rune is printable rune is space rune For '℃': is graphic rune is printable rune is symbol rune For 'ᾭ': is graphic rune is rune is upper case rune For '十': is graphic rune is letter rune is printable rune
3️⃣正确做法:转[]rune再截取Rune是Go中的Unicode码点类型,一个rune代表一个完整的字符。 展开代码语言:GoAI代码解释packagemainimport"fmt"funcmain(){str:="Go测试"//✅正确:先转rune切片,再截取runes:=[]rune(str)sub:=string (runes[:3])//取前3个字符fmt.Println(sub)//输出:Go测}4️⃣面试加分项:性能优化如果字符串很长,频繁转[]rune会有内存开销。 str[:n]字节(byte)纯英文/ASCII中文乱码[]rune(str)[:n]字符(rune)含中文/多语言内存开销rangestr字符(rune)遍历处理性能较好记忆口诀Go串底层是字节,中文三字节别切 要想截取不乱码,转成rune再操作。✅避坑指南:涉及用户输入、国际化场景,永远不要假设1字符=1字节!
unicode/utf8 主要负责rune和byte之间的转换 unicode/utf16 负责rune和uint16数组之间的转换 注意: 在Go语言中,一个rune就代表一个unicode编码,'中 ',就是一个rune。 rune) bool // 是否图形字符 func IsLetter(r rune) bool // 是否字母 func IsLower(r rune) bool // 是否小写字符 func IsMark , r rune) bool // 是否是RangeTable中的一个 func IsPrint(r rune) bool // 是否可打印字符 func IsPunct(r rune) bool // ) 编码和解码rune到byte funcDecodeRune(p[]byte)(r rune,sizeint) funcEncodeRune(p[]byte,r rune)int utf16包 较少使用
如何获取字符串每一个字节 rune 的使用 使用for range 遍历字符串 使用字节切片构造字符串 使用rune切片构造字符串 计算字符串长度 字符串是不可变的 下面我们就开始本节的学习 如何获取字符串的每一个字节 i++{ c := fmt.Sprintf("%c",s[i]) fmt.Println(c) } } 现在应该已经掌握了这个知识点,我们进行下一个 ---- rune rune 是什么? rune 表示一个代码点。 代码点无论占用多少个字节,都可以用一个 rune 来表示 使用方法 只要把字符串转换成rune的切片即可 package main import "fmt" func main() { s := image.png 使用切片rune 构造字符串 package main import "fmt" func main() { chars := []rune{97,98,12500} s
3️⃣正确做法:转[]rune再截取Rune是Go中的Unicode码点类型,一个rune代表一个完整的字符。 展开代码语言:GoAI代码解释packagemainimport"fmt"funcmain(){str:="Go测试"//✅正确:先转rune切片,再截取runes:=[]rune(str)sub:=string (runes[:3])//取前3个字符fmt.Println(sub)//输出:Go测}4️⃣面试加分项:性能优化如果字符串很长,频繁转[]rune会有内存开销。 str[:n]字节(byte)纯英文/ASCII中文乱码[]rune(str)[:n]字符(rune)含中文/多语言内存开销rangestr字符(rune)遍历处理性能较好记忆口诀Go串底层是字节,中文三字节别切 要想截取不乱码,转成rune再操作。✅避坑指南:涉及用户输入、国际化场景,永远不要假设1字符=1字节!
与最初版本实现的不同点是,打印变量r的值而不是s[i]. range作用于字符串时会返回两个值,值1是rune的下标索引,值2是rune本身。 切片,然后遍历rune切片,实现代码如下。 相比最初版本,这里直接打印每个rune索引。 因此,如果我们想迭代全部的rune,推荐使用方法一。 相反,通过字符串的rune切片,直接访问切片中的第i个值便是我们想要获取的第i个rune字符,这种情况下,我们应该选用方法二。 下面的代码直接输出字符串s中第5个字符。
// 预定义字符是: // 单引号(') // 双引号(") // 反斜杠(\) func Addslashes(str string) string { tmpRune := []rune{} strRune := []rune(str) for _, ch := range strRune { switch ch { case []rune{'\\'}[0], []rune{'"'}[0], [ ]rune{'\''}[0]: tmpRune = append(tmpRune, []rune{'\\'}[0]) tmpRune = append(tmpRune, ch) default func Stripslashes(str string) string { dstRune := []rune{} strRune := []rune(str) strLenth := len( strRune) for i := 0; i < strLenth; i++ { if strRune[i] == []rune{'\\'}[0] { i++ } dstRune =
) rune, s string) string:将s中满足f(rune)的字符替换为f(rune)的返回值。 如果f(rune)返回负数,则相应的字符将被删除。 (rune)的字符。 如果没有满足 f(rune) 的字符,则返回 -1。 如果没有满足 f(rune) 的字符,则返回 -1。
英文字母的字符串 "你好abc啊哈哈" 代码实现 package main import"fmt" func main() { src := "你好abc啊哈哈" dst := reverse([]rune (src)) fmt.Printf("%v\n", string(dst)) } func reverse(s []rune) []rune { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } return s } 解释 rune关键字,从golang源码中看出,它是int32的别名 由于rune可表示的范围更大,所以能处理一切字符,当然也包括中文字符。在平时计算中文字符,可用rune。 因此将字符串转为rune的切片,再进行翻转,完美解决。
} type MyString string // 接口的实现 func (ms MyString) FindVowels() []rune { var vowels []rune for _, rune := range ms { if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune } 实现接口 type MyString string // 接口的实现 func (ms MyString) FindVowels() []rune { var vowels []rune for _, rune := range ms { if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune == 'u' { vowels = append(vowels, rune) } } return vowels } 练习使用接口 type
而在 Go 中,“字符”的概念被称为 rune,它是表示 Unicode 代码点的整数。这篇 Go 官方博客文章是一个很好的入门资源。 需要注意的是,RuneCountInString 的运行时间取决于字符串的大小,因为它需要逐个解码每个 UTF-8 rune。 fmt.Println("Rune count:", utf8.RuneCountInString(s))// range 循环对字符串进行了特殊处理,会解码每个 rune 及其在字符串中的偏移量。 examineRune(runeValue) }}func examineRune(r rune) {// 用单引号括起来的值是 rune 字面量。 我们可以直接将一个 rune 值与 rune 字面量进行比较。