1/3
2/3
3/3
013 For-Range 另一种循环格式 | 目标是成为Golang大师
一只地鼠君
2021年03月23日 11:04

视频: https://www.bilibili.com/video/BV1XV411Y7h7/​

依然只有一种循环

在上节,我们首次接触到了循环结构,并得知在Golang中只有一种循环——For循环

下面要介绍另一种循环,实际上它是For循环的另一种格式,所以与上面的说法并不矛盾

For-Range

For-Range循环用于遍历Golang中不同的数据类型,它们分别是:

  • 数组(array)/切片(slice)

  • 字符串(string)

  • 字典(map)

  • 通道(channel)

因为到目前为止,我们只接触过字符串,所以下面对For-Range的讨论由字符串展开

后面学到对应的数据类型时,我们会重新拾回For-Range,所以Don’t worry~

下面是For-Range循环遍历字符串时的完整格式:

  • 注意到上图分别短声明了两个变量index/value,短声明的右边是range关键词加某个字符串

  • 当然也是有For循环局部作用域的问题,index/value只能在For循环内使用

  • index与value都是可选的

在开始接触For-Range之前,我们需要稍微了解一些字符串编码的知识

再论字符串

字符串是编程之旅中最常用的基本数据类型之一,但事实上,它也并没有那么的基本,因为它是由字节(byte)组成的一个序列

通过Golang内置函数,我们可以得知一个字符串占了多少字节:

这个字符串占了5个字节,没毛病啊,因为它一共只有5个字符

再看看一个包含中文的字符串的长度:

Whattt??? 结果显示是11,但是明明只有7个字啊?? 我悟了,原来计算机还没我聪明

在Golang中,字符采用Unicode字符集表示(万国码,可以表示全世界的文字),用UTF-8规则进行编码,像这些ASCII字符用1个字节表示,其余字符用1~4个字节表示

在上面的中文例子中:

  • "nbody&#​34;有5个英文字符,占5个字节

  • 一个中文字符用3个字节表示,所以"编程&#​34;占了6个字节

  • 5+6=11,所以len(s)的结果是11

遍历字符串

遍历的意思是,比如有一个字符串,我将它的每一个字符访问个遍

所以现在的问题是,如何访问一个字符串的其中一个字符?答案是: 利用它的索引(index)访问即可

所谓索引,就是里面的位置,它是0,的位置是1,的位置是4。索引是从0开始计数的

通过这样的格式就可以访问它的某个字符:

等等,为什么输出的是一堆数字?这里要追溯到基本数据类型一节中,我们曾介绍了两个很特别的类型:

  • byte(字节类型)是uint8的别名

  • rune(代表一个Unicode字符)是int32的别名

也就是说一个字节实际上就是一个8位的无符号整数,所以我们看到的是一堆数字

我们需要将数字转换成它对应的Unicode字符,可以利用函数与标记:

再利用上节所学的For循环,就可以遍历一个字符串了:

两种For格式的区别

两种格式的区别主要在于,遍历字符串时的行为不同:

  • For-Standalone会遍历字符串的每一个字节(Byte类型)

  • For-Range会遍历字符串的每一个Unicode字符(Rune类型)

下面通过一个例子来理解,我们把上一个例子换成包含中文的字符串:

最后输出了6个乱码,这是因为For-Standalone格式的循环会遍历每一个字节,但最后6个字节是每3个字节表示一个中文字符,这里把它拆分了,所以输出乱码

用For-Range格式来遍历:

标记表示输出一个整数,可以看到,For-Range同时遍历了索引和对应的Unicode字符

利用标记可以看到迭代时的字符的类型:

所以遍历字符串时,应该用For-Range格式,才能输出正确的rune类型字符

忽略value

假如只想遍历索引,这时可以无视value,因为value是可选的:

忽略index

很多情况下,我们只需要遍历value,可以利用iota常量计数器一节中所学的空标识符()来忽略index:

忽略index和value

也可以把两者都忽略掉,但很少这样使用:

总结

感觉这节主角其实是For-Range,但大部分内容都是在讲Golang中的字符串编码问题,有点喧宾夺主…

but,如果不讲清楚这个问题,那For-Range就无法展开讨论了 =。=

anyway,有所收获就行~

下节,我们将介绍Golang中的一个异类,利用它,可以构成非常复杂的程序结构。

如果你看过《火影忍者》,你可以称它为Golang中四代火影的拿手好戏——飞雷神之术

goto next_time…

原文地址: https://nbody1996.gitee.io/becoming_gopher/posts/013/