前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言中字符串的计算方式

Go语言中字符串的计算方式

原创
作者头像
似水流年o
修改2022-02-21 10:23:00
9840
修改2022-02-21 10:23:00
举报
文章被收录于专栏:编程学习收获编程学习收获

开门见山,抛出结论:"Go语言中字符串第i项并不一定是第i个字符"

初看这句话可能不太理解,下面我举例说明

代码语言:javascript
复制
func main() {
	var name string = "zhang"
	fmt.Println(name[1]) //print 104
}

name[1]对应的值是h ,h对应的值是104,有同学要说了,这不就证明"Go语言中字符串第i项是第i个字符"吗? 莫着急,我们接着看下面的一个案例:

代码语言:javascript
复制
func main() {
	var name string = "哈hang"
	fmt.Println(name[1]) //print 147
}

字符'z'改成了字符'哈'name[1]结果就发生了变化。

通过上面的两个案例,我们已经证明了:"Go语言中字符串第i项并不一定是第i个字符"。那么怎么才能使得案例2和案例1的结果一致呢?如下处理案例3

代码语言:javascript
复制
func main() {
	var name string = "哈hang"
	fmt.Println([]rune(name)[1]) //print 104
}

出现案例1案例2结果差异的原因:Go语言中基础数据类型:string字符串类型底层数据结构是数组,它是byte类型,在JAVA语言中引用数据类型:String字符串类型底层数据结构也是数组,它是char类型。而Go语言中默认字符是通过UTF-8进行编码,我们知道在UTF-8编码中:"一个中文等于三个字节,中文标点占三个字节,一个英文字符等于一个字节,英文标点占一个字节。"

代码语言:javascript
复制
func main() {
	var name string = "哈hang"
	fmt.Println([]rune(name), fmt.Sprintf("%d", len([]rune(name)))) //[21704 104 97 110 103] 5
	fmt.Println([]byte(name), fmt.Sprintf("%d", len([]byte(name)))) //[229 147 136 104 97 110 103] 7
}

所以,Go中才出现了案例1案例2的差异,但JAVA语言中并不会出现上述的现象

接下来,解释下案例3rune的用法,引用官方的原话

代码语言:javascript
复制
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.

//int32的别名,几乎在所有方面等同于int32
//它用来区分字符值和整数值

type rune = int32

在Go语言中定义字符有两种方式:

  • unit8 类型( byte <==> unit8 ,两者同意不同名),表示 ASCII 码的一个字符,占用 1 个字节。
  • rune 类型,代表一个 UTF-8 字符,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型。 rune 类型等价于 int32 类型,占用 4 个字节。

综上案例3也可以写成:

代码语言:javascript
复制
func main() {
	var name string = "哈hang"
	fmt.Println([]int32(name)[1]) //print 104
}

由于Go语言字符串底层是byte类型,可以预想,通过内置函数len()获取字符串的长度实际值与我们预想值会不一样。如下案例4

代码语言:javascript
复制
func main() {
	var name string = "哈hang"
	fmt.Println(len(name))  //预想值是5,实际值是7
}

如果我们需要预期值5,应该如何实现呢?如下案例5

代码语言:javascript
复制
import (
	"fmt"
	"unicode/utf8"
)

func main() {
	var name string = "哈hang"

	//以下两种都可以得到str的字符串长度

	//golang中的unicode/utf8包提供了用utf-8获取长度的方法
	fmt.Println("RuneCountInString:", utf8.RuneCountInString(name))  //5

	//通过rune类型处理unicode字符
	fmt.Println("rune:", len([]rune(name)))  //5
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档