👋 一起朝着目标前进吧!

013 For-Range 另一种循环格式

视频: 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内置函数len,我们可以得知一个字符串占了多少字节: "hello"这个字符串占了5个字节,没毛病啊,因为它一共只有5个字符 再看看一个包含中文的字符串的长度: Whattt??? 结果显示是11,但是明明只有7个字啊?? 我悟了,原来计算机还没我聪明 在Golang中,字符采用Unicode字符集表示(万国码,可以表示全世界的文字),用UTF-8规则进行编码,像0-9a-zA-Z这些ASCII字符用1个字节表示,其余字符用1~4个字节表示 在上面的中文例子中: "nbody"有5个英文字符,占5个字节 一个中文字符用3个字节表示,所以"编程"占了6个字节 5+6=11,所以len(s)的结果是11 遍历字符串 遍历的意思是,比如有一个字符串"hello",我将它的每一个字符h、e、l、l、o访问个遍 所以现在的问题是,如何访问一个字符串的其中一个字符?答案是: 利用它的索引(index)访问即可 所谓索引,就是h在hello里面的位置,它是0,e的位置是1,o的位置是4。索引是从0开始计数的 通过SomeString[索引]这样的格式就可以访问它的某个字符: 等等,为什么输出的是一堆数字?这里要追溯到基本数据类型一节中,我们曾介绍了两个很特别的类型: byte(字节类型)是uint8的别名 rune(代表一个Unicode字符)是int32的别名 也就是说一个字节实际上就是一个8位的无符号整数,所以我们看到的是一堆数字 我们需要将数字转换成它对应的Unicode字符,可以利用fmt.Printf函数与%c标记: 再利用上节所学的For循环,就可以遍历一个字符串了: 两种For格式的区别 两种格式的区别主要在于,遍历字符串时的行为不同: For-Standalone会遍历字符串的每一个字节(Byte类型) For-Range会遍历字符串的每一个Unicode字符(Rune类型) 下面通过一个例子来理解,我们把上一个例子换成包含中文的字符串: 最后输出了6个乱码,这是因为For-Standalone格式的循环会遍历每一个字节,但最后6个字节是每3个字节表示一个中文字符,这里把它拆分了,所以输出乱码 用For-Range格式来遍历: %d标记表示输出一个整数,可以看到,For-Range同时遍历了索引和对应的Unicode字符 利用%T标记可以看到迭代时的字符的类型: 所以遍历字符串时,应该用For-Range格式,才能输出正确的rune类型字符 忽略value 假如只想遍历索引,这时可以无视value,因为value是可选的: 忽略index 很多情况下,我们只需要遍历value,可以利用iota常量计数器一节中所学的空标识符(_)来忽略index: 忽略index和value 也可以把两者都忽略掉,但很少这样使用:...

2021年03月18日 · nbody1996

012 For循环语句

视频: https://www.bilibili.com/video/BV1iX4y1V7z4/ 循环结构 在上节,我们学习了选择结构,有两种方法实现: If语句 Switch语句 today,我们接触一种全新的程序结构——循环结构,它能让代码更加有趣儿~ so,什么是循环结构?当某个条件成立时,周而复始地做某些事 比如: 人的一生如果还活着(条件),就应该不断学习(某些事) 只有一种循环 学过别的编程语言的盆友,估计已经知道,有三种循环: For循环 While循环 Do-While循环 但是在Golang中,只有一种循环——For循环 像"二八定律",20%的事物占了80%的重要性。Golang的设计遵循着"Less is More"(以少为多)的哲学思想 For循环语句 For循环的完整格式如下: 有4个部份: init part(初始化部份),只在第一次循环开始前执行一次(有局部变量作用域) condition part(条件判断部份),在每次循环开始前,判断一次,如果为true则继续下一轮循环,否则退出循环 post part(变量变化部份),在每次循环结束后,执行一次 花括号内的for循环代码块,在条件成立时,被执行一次 理解代码最容易的方式当然是"Show me the demo": 流程是这样的: 执行i := 0 判断0 < 3,为true,执行循环 fmt.Println(i) -> 0 执行i++,等于i += 1,等于i = i + 1,这时i从0变为1 判断1 < 3,为true,执行循环 fmt.Println(i) -> 1 执行i++,这时i从1变为2 判断2 < 3,为true,执行循环 fmt.Println(i) -> 2 执行i++,这时i从2变为3 判断3 < 3,为false,退出循环 在Golang中,前面的init/condition/post part三个部份都是可选的...

2021年03月08日 · nbody1996

011 条件分支之Switch语句

视频: https://www.bilibili.com/video/BV1yb4y1X78q/ 一个头皮发麻的IF语句 假设要写一个判断星期几的程序,使用If语句可以这样写: 且不说代码量大,就可阅读性来说,就叫人非常头大 同样是选择结构,这时可以用Switch语句来代替层级(ladder)的If语句 Switch语句 switch语句的完整格式如下: statement是前置语句(一般用来短声明变量) expression是一个表达式 一个case就是一个分支,case可以有多个表达式,用逗号隔开 switch语句会从上到下,从左到右(一个case多个表达式的情况)检测case表达式与switch表达式是否相等,相等则进入对应流程 如果所有case都不匹配,则执行default的流程(就像If语句中的Else一样),default是可选的 使用switch语句改善判断星期几的程序: 看着舒服多了~ 和If语句类似,在Switch前置语句中声明的变量,也只能在Switch代码块内使用,可以尝试下在Switch外使用day变量,看看会不会报错 在Golang中,Switch语句的statement和expression都是可选的,所以有3种变体格式,下面一一介绍 省略statement的Switch 格式: 基本功能和完整的Swtich一样,只是缺少了前置语句,来看个例子加深理解: 省略expression的Switch 格式: 注意分号不能省略,否则Golang会认为是expression 忽略expression时,expression默认是布尔值true 两者都省略的Switch 格式: 基本功能和省略expression的Switch一样,可以用来代替If语句 比如有如下If语句: 用Switch语句替代: 运行试一下: Break语句 break(中断)语句可用于终止Switch语句的执行,在break出现后的代码不会被执行 学过别的编程语言的盆友,可能已经发现了Golang中Switch语句的不同点了 Golang会自动在case代码块的最后,自动补充上break语句的功能,但是我们也可以主动添加break来提前退出Switch语句 举个例子: fmt.Println("after", 1)并不会被执行,因为在此之前我们已经break出去了 试试: Fallthrough语句 fallthrough语句可以在执行完当前case代码块后,继续执行下一个case的代码块 举个例子: 毫无疑问,case 0代码块将会被执行,随后fallthrough语句的出现导致case 1代码块也会被执行 试试: 注意,fallthrough只能放在case代码块的最后一行,否则将会报错: 总结 下节介绍一种新的程序结构 —— 循环结构 bye~...

2021年03月02日 · nbody1996

010 条件分支之If语句

视频: https://www.bilibili.com/video/BV16r4y1A7jG/ 条件分支 至今为止,我们接触的程序结构都是顺序结构,是从上到下,依次执行的: 下面介绍另外一种结构——选择结构: 根据条件的不同,使程序走向不同的流程 在Golang中,这里的条件是指布尔值(bool),所以下面先介绍一下条件操作符 条件操作符一览 条件操作符是指作用于一个或两个值,结果是布尔值的操作符。可以细分成两种: 关系运算符 == 等于 != 不等于 > 大于 >= 大于或等于 < 小于 <= 小于或等于 逻辑运算符(作用于布尔值) && 逻辑与,两者皆为true时,结果为true,否则为false(具有短路特性) || 逻辑或,两者其一为true时,结果为true,否则为false(具有短路特性) ! 取反,true变false,false变true 看个例子: If语句 单独的If语句有如下格式: condition(条件)必须是一个布尔值,如果为true时,则执行花括号内的代码块,否则不执行 举个例子,比如成绩大于90分为"优秀": 成绩大于或等于70且小于90为"中等": 这里的 score >= 70 && score < 90 最终结果是一个布尔值true,因为: score >= 70 为 true score < 90 为 true true && true 为 true 等价于下面例子:...

2021年02月26日 · nbody1996

009 常量中的iota自增计数器

视频: https://www.bilibili.com/video/BV1gN41197Kf/ 什么是iota iota是golang中的一个关键词,只能用于常量的声明中,它在某些方面可以简化常量的声明 下面来看一个例子: 上面代码非常明确,声明a/b/c三个常量,它们的值为0~2。 根据目前已有知识,貌似无法再简化了。但是一旦拥有了iota之后,可以进一步简化: WTF? 这叫简化?多了好几个字呢 =w= 别着急,还能再一步简化: 因为b与c没有提供初始值,它们与上一行的值和类型都保持一致了(上节的内容) 执行试试看: 通过上面的例子,我们得知,iota是: 一个从0开始计数的计数器(counter) 每增加一行常量,计数加1 只能用于常量的声明中 从1开始计数 iota是从0开始计数的,如果我想声明一组1~7的常量(像星期一至星期天)怎么办? 能让iota从1开始计数吗? 答案是不能,但是有一种巧妙的方法可以声明一组1~7的常量: 因为b没有初始值,它的值等于上一行a的值,而a的值为iota + 1=> 0 + 1,到b这一行iota的值变成了1,所以iota + 1 => 1 + 1。其它同理可得 下面继续介绍另外一个巧妙的方法达到同一目的 跳过某一值 假如我想声明一组常量,值是0、2、4,怎么做? 可以这样做: 还有别的办法吗?有,这里引入空标识符(blank identifier)的知识 空标识符提供一种在赋值中忽略某个值的方法,用下划线(_)表示它,举个例子: 利用空标识符同样可以达到目的: 从1开始计数的例子可以改为: iota常见误区 iota 只是在同一个 const 常量组内递增,每当有新的 const 关键字时,iota 计数会重新开始 iota 只能用于常量声明中,不能用于变量声明 总结 see ya~...

2021年02月25日 · nbody1996