Go语言rune与字符串转换的密切关系解析

 更新时间:2022年12月12日 10:32:50   作者:捶捶自己  
这篇文章主要为大家介绍了Go语言rune与字符串转换的密切关系示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

介绍rune类型

golang中rune与字符串转换的密切关系

rune 类型是 Go 语言的一种特殊数字类型。在 builtin/builtin.go 文件中,它的定义是type rune = int32.官方对它是这么解释的:rune 是类型 int32 的别名,在所有方面都等价于它,用来区分字符值跟整数值.使用单引号定义 ,返回采用 UTF-8 编码的 Unicode 码点.Go 语言通过 rune 处理中文,支持国际化多语言。

为什么要给int32取一个别名rune呢,为什么不直接使用int32?

这是因为别名的使用在大型项目重构中作用最为明显,它能解决代码升级或迁移过程中可能存在的类型兼容性问题。在go语言中还有另外一个类型别名也是用来处理字符的,要知道在go语言中可没有char这个类型,因此对于字符的处理就要特别对待。

rune如何处理字符?

rune主要表示字符码点,特别在处理中文方面尤其有效。下面是例子

func main() {
   s := "我是一个gophers"
   fmt.Println(len(s))
   fmt.Println(len([]rune(s)))
}
运行结果:
19
11

通过对比我们可以发现中文字符每个占据3个字节,如果使用byte则需要三个不同的值,而使用rune刚好可以完整表达。

引出golang中关于字符串的说明

  • Go 源代码始终为 UTF-8。
  • 字符串可以包含任意字节。
  • 字符串文字中不包含字节级转义符时字符串始终包含有效的 UTF-8 序列。
  • 代表 Unicode 码点的字节序列称为 rune
  • 在 Go 中不会保证字符串中的字符被规范化。

值得注意的地方

在前面已经提到过,golang中没有char这个概念,有的只是byte(uint8)单个字符的代表。因此要如何实现string呢?这个待会再讲。我们现在主要介绍string遍历过程中的问题。请看下面的例子

func main() {
   s := "我是一个gophers"
   for i, v := range s {
      fmt.Printf("第%d个值,类型为%T结果为:%v\n", i, v, string(v))
   }
   for i, v := range s {
      fmt.Printf("第%d个值,类型为%T结果为:%v\n", i, v, string(s[i]))
   }
}
运行结果:
第0个值,类型为int32结果为:我
第3个值,类型为int32结果为:是
第6个值,类型为int32结果为:一
第9个值,类型为int32结果为:个
第12个值,类型为int32结果为:g
第13个值,类型为int32结果为:o
第14个值,类型为int32结果为:p
第15个值,类型为int32结果为:h
第16个值,类型为int32结果为:e
第17个值,类型为int32结果为:r
第18个值,类型为int32结果为:s
-------------------------------------------
第0个值,类型为int32结果为:æ 
第3个值,类型为int32结果为:æ 
第6个值,类型为int32结果为:ä 
第9个值,类型为int32结果为:ä 
第12个值,类型为int32结果为:g
第13个值,类型为int32结果为:o
第14个值,类型为int32结果为:p
第15个值,类型为int32结果为:h
第16个值,类型为int32结果为:e
第17个值,类型为int32结果为:r
第18个值,类型为int32结果为:s

通过比对和循环我们可以得知,golang中对于string的循环,如果是中文则需要注意他的下标序号是以3为差值,字符是以1为差值.通过s[i]v的比对可以知道为什么golang中需要选择rune作为字符串的转换值.如果转化是一个中文的话,一个字节的byte是无法容纳的,而rune解决了这个问题.

介绍string类型

关于string类型,在go标准库builtin中有如下说明:

// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string

也就是说:string是8位字节的集合,通常但不一定代表UTF-8编码的文本.string可以为空,但是不能为nil.string的值是不能改变的. 而在go语言的源码中我们可以看到string的构成:

type stringStruct struct {
   str unsafe.Pointer
   len int
}

stringStruct就是string的一个对象,这个str就是一个指向字符数组首位的一个指针.len就是这个字符串的长度.那么这个数组指的是什么呢?其实就是一个[]byte,string内部就是通过这个字符切片组成的。而这个str就是指向了这个切片的首地址.因此也解释了一个现象,为什么[]byte中的值可以被修改,而string中的值无法被修改.也正因如此copy内置函数才可以将string类型复制为[]byte类型.

字符串的值不能被更改,但可以被替换. string在底层都是结构体stringStruct{str: str_point, len: str_len},string结构体的str指针指向的是一个字符常量的地址,这个地址里面的内容是不可以被改变的,因为它是只读的,但是这个指针可以指向不同的地址.

为什么替换字符时string比[]byte效率慢?

由于每次替换string的值时,stringstr指针无法进行改变指向,因此程序内部就需要去新开辟一个指针指向新的[]byte,然后先前分配的string内存就会被GC所回收.这是导致string相较于[]byte操作低效的根本原因.

思考string、byte、rune之间的关系

Go语言把字符分 byte 和 rune 两种类型处理.byte 是类型 unit8 的别名,用于存放占 1 字节的 ASCII 字符,如英文字符,返回的是字符原始字节.rune 是类型 int32 的别名,用于存放多字节字符,如占 3 字节的中文字符,返回的是字符 Unicode 码点值.

总结

  • string无法进行修改,只能进行替换
  • string底层由一个指针指向[]byte
  • rune主要用来表示码点并处理大于1字节小于4个字节的特殊字符
  • 中文字符每个码点占据多个字节,并且在string循环中通过rune表示

以上就是Go语言rune与字符串转换的密切关系解析的详细内容,更多关于Go rune字符串转换的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言七篇入门教程一简介初识

    Go语言七篇入门教程一简介初识

    本篇是Go语言七篇入门系列第一篇Go语言初识及简单介绍,从现在开始一起打开Go语言的学习大门吧,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Go语言中定时器cron的基本使用教程

    Go语言中定时器cron的基本使用教程

    这篇文章主要给大家介绍了关于Go语言中定时器cron使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Go语言反射reflect.Value实现方法的调用

    Go语言反射reflect.Value实现方法的调用

    本文主要介绍了Go语言反射reflect.Value实现方法的调用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • golang struct扩展函数参数命名警告解决方法

    golang struct扩展函数参数命名警告解决方法

    今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,需要的朋友可以参考下
    2017-02-02
  • 使用Go Validator有效验证数据示例分析

    使用Go Validator有效验证数据示例分析

    作为一名开发者,确保Go应用中处理的数据是有效和准确的非常重要,Go Validator是一个开源的数据验证库,为Go结构体提供强大且易于使用的数据验证功能,本篇文章将介绍Go Validator库的主要特点以及如何在Go应用中使用它来有效验证数据
    2023-12-12
  • Go 语言的指针的学习笔记

    Go 语言的指针的学习笔记

    这篇文章主要介绍了Go 语言的指针的学习笔记,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Go语言实现关闭http请求的方式总结

    Go语言实现关闭http请求的方式总结

    面试的时候问到如何关闭http请求,一般人脱口而出的是关闭response.body,这是错误的。本文为大家整理了三个正确关闭http请求的方法,希望对大家有所帮助
    2023-02-02
  • Golang分布式锁简单案例实现流程

    Golang分布式锁简单案例实现流程

    分布式锁是控制分布式系统之间同步访问共享资源的一种方式。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源时,需要通过一些互斥手段来防止彼此之间的干扰以保证一致性,在这种情况下,就需要使用分布式锁了
    2022-12-12
  • Go工具链之go tool fix用法详解

    Go工具链之go tool fix用法详解

    go tool fix 是 Go 工具链中的一个命令,作用是把指定 Go 程序代码包中的的所有旧版本代码修正为新版本的代码,本文将简单介绍一下go tool fix的使用方法,感兴趣的小伙伴可以参考阅读下
    2023-07-07
  • Go语言官方依赖注入工具Wire的使用教程

    Go语言官方依赖注入工具Wire的使用教程

    依赖注入是一种实现控制反转且用于解决依赖性问题的设计模式。Golang 中常用的依赖注入工具主要有 Inject 、Dig 等。但是今天主要介绍的是 Go 团队开发的 Wire,一个编译期实现依赖注入的工具,感兴趣的可以了解一下
    2022-09-09

最新评论