为什么 go 中字符串不能用下标访问

五行缺金 · · 1027 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在大多数编程语言中,字符串是可以直接通过下标访问的,但是在使用 go 语言的时候,直接使用下标访问有时候会出现一些乱码。
<!--more-->

数组

在解决这个问题之前,要先了解一个东西--数组:数组是用于存储多个相同类型数据的集合。并且数组在申请内存的时候,是一次申请一块连续的内存。比如我们创建一个数组,里面存了这几个元素。

数组空间

由于内存是连续的,元素的类型也是相同的,所以每个元素占用的内存空间也是固定的,比如 java 中 char 类型占用两个字节。数组的内存空间是平等划分的,这样就可以解释为什么可以靠下标访问了。

在可以用下标访问的语言中,字符串都是按照字符编码的。也就是说,你将字符串 “abcd” 赋给变量 a,本质上是创建了一个字符数组用来存放字符串。但是在 go 语言里不一样,go 语言的字符型是按照字节编码的,什么意思呢? 26 个英文字母,每个英文字母占一个字节,在 go 语言的 string 里面就占用一个字节。中文日文韩文就不一样了, go 语言内建只支持 utf8 编码,在 utf8 里面,有一部分汉字占用 3 个字节,一部分汉字占用 4 个字节。比如 "巧" 这个字,打印一下它的长度,发现这个 string 占用 3 个字节,加上 "a" 之后占用 4 个字节,应该能理解按字节编码的意思了。

汉字字母

编码

为什么要 go 要选择按照字节来编码呢,这其实是为了节省空间。想象一下,在UTF-8编码中,中文有些要三个字节,有一些要占用四个字节,而英文字母只需要占用一个字节。一个中文算一个字符,一个英文字母也算一个字符,但是占用的内存相差很大,假设有一个超长字符串,里面有英文字符远多于中文字符,如果按字符来存储,每个字符要分配四个字节。因为低于四个字节,有可能有些中文就不能正常存储了,在这种情况下,每存储一个英文字母,就要浪费三个字节的内存空间。

底层实现和其它语言就不一样,不同类型的字符占用的内存空间都不同,当然也就没有办法按照下标访问了,不信可以试试。
请输入图片描述

a[0] 是 97,等于字母 a 的 ascii 码,a[1] 是 229,显然不会是汉字 "巧" 的 utf8,事实它是 utf8 编码的第一字节的值。
请输入图片描述

打完收工,到这里弄清楚了 go 中 string 不能按照下标访问的原理了

公众号:没有梦想的阿巧 后台回复 "群聊",一起学习,一起进步

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:五行缺金

查看原文:为什么 go 中字符串不能用下标访问

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

1027 次点击  
加入收藏 微博
1 回复  |  直到 2020-10-22 14:20:08
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传