Go chapter1
前言
因为最近这段时间被拉去打一个程序开发的比赛,所以花几天学了一下go语言。
接下来打算把学习go的笔记更一下,后面再写一些关于go的安全编程的内容。
基本结构
包和函数
1 |
|
package关键字声明了代码所属的包。
在package关键字之后,代码使用了import关键字来导入自己将要用到的包。一个包可以包含任意数量的函数。
fmt包提供了用于格式化输入和输出的函数。
func关键字用于声明函数,在本例中这个函数的名字就是main。每个函数的体都需要使用大括号包围,这样go才能知道每个函数从何处开始,又在何处结束。
当我们运行一个程序的时候,它总是从 main 包的 main 函数开始运行。如果 main 不存在,编译器将报错。
每次用到被导入包的某个函数时,我们都需要在函数的名字前面加上包的名字以及一个点号作为前缀。
唯一允许的大括号放置风格
go对于大括号({})的摆放非常挑剔。左大括号 { 与func关键字位于同一行,而右大括号 } 则独占一行。这是go语言唯一允许的大括号放置风格,除此之外的其他大括号放置风格都是不被允许的。
如果用户尝试将左大括号和 func 关键字放在不同的行里面,那么go编译器将报告一个语法错误。
被美化的计算器
执行计算
注释
go语言的注释和C语言一样
单行注释
1 |
|
多行注释
1 |
|
算术运算符
编程语言中一般通用的常规运算符。
运算符 | 功能 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 模 |
格式化输出
Println输出函数
这个函数输出的内容会在后面加一个换行,也就是\n
。
1 |
|
Printf格式化输出函数
1 |
|
Printf 接收的第一个参数总是文本,第二个参数则是表达式,而文本中包含的格式化变量%v
则会在之后被替换成表达式的值。
这个和C语言中的printf
很相似。
%v是通用类型的意思
虽然Println会自动将输出的内容推进至下一行,但是Printf和Print却不会那么做。对于后面这两个函数,用户可以通过在文本里面放置换行符\n
来将输出内容推进至下一行。
如果用户指定多个格式化变量,那么Printf函数将按顺序把它们替换成相应的值。
1 |
|
Printf除可以在句子的任意位置将格式化变量替换成指定的值之外,还能够调整文本的对齐位置。
用户可以通过指定带有宽度的格式化变量%4v,将文本的输出宽度填充至4个字符。
当宽度为正数时,空格将被填充至文本左边,而当宽度为负数时,空格将被填充至文本右边。
1 |
|
常量和变量
常量
1 |
|
变量
1 |
|
\
走捷径
一次声明多个变量
每一行单独声明一个变量
1 |
|
一次声明一组变量
1 |
|
同一行声明多个变量
1 |
|
需要注意的是,为了保证代码的可读性,我们在一次声明一组变量或者在同一行声明多个变量之前,应该先考虑这些变量是否相关。
增量并赋值操作符
有几种快捷方式可以让我们在赋值的同时执行以下操作。
1 |
|
常见的有,这些概念一般其他编程语言中也有
符号 | 功能 |
---|---|
+= | 加上符号右边的值后再赋值 |
-= | 减上符号右边的值后再赋值 |
*= | 乘以符号右边的值后再赋值 |
/= | 除以符号右边的值后再赋值 |
%= | 模运算符号右边的值后再赋值 |
自增运算符、
用户可以使用i++
执行加1操作
但是go并不支持++i
这种C语言中的操作。
1 |
|
数字游戏
使用rand包来生成伪随机数
下列代码中,会显示一个110之间的数字。这个程序会先向Intn函数传入数字10以返回一个09的随机数,然后把这个数字加一并将其结果赋值给变量num。
传入给Intn函数的10会让rand生成从零开始的十个数字之间的随机数,即一个09的数字,所以如果我们要求是110则需加上一个1。
1 |
|
虽然 rand 包的导入路径为math/rand,但是我们在调用 Intn 函数的时候只需要使用包名 rand 作为前缀即可,不需要使用整个导入路径。
循环和分支
真或假
布尔变量
注意,go中0和1不能作为布尔值使用。
1 |
|
go语言标准库里面有好多函数都会返回布尔值。
例如如下代码
代码中使用了strings包的Contais函数来检查command变量是否包含单词”outsize”,如果包含则返回为true,否则返回false
1 |
|
比较
比较运算符
符号 | 含义 |
---|---|
== | 相等 |
!= | 不相等 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
表中的运算符既可以比较文本,又可以比较数值。 |
比较结果返回的是布尔值。
1 |
|
使用if实现分支判断
如下所示,计算机可以使用布尔值或者比较条件在if语句中选择不同的执行路径。
1 |
|
这里要注意,else if 和 else 都要紧跟在前一个大括号后面,否则会报错。
else if语句和else语句都是可选的。当有多个分支路径可选时,可以重复使用else if直到满足需要为止。
逻辑运算符
基本都是编程语言通用的。
符号 | 含义 |
---|---|
|| | 逻辑或 |
&& | 逻辑与 |
! | 逻辑非 |
1 |
|
跟大多数编程语言一样,go也采用了短路逻辑:如果位于 || 运算符之前的第一个条件为真,那么位于 || 运算符之后的条件就可以被忽略,没有必要再对其进行求值。
&& 运算符的行为与 || 运算符正好相反:只有在两个条件都为真的情况下,运算结果才为真。
逻辑非运算符 ! 可以将一个布尔值从 false 变为 true,或者将 true 变为 false。
使用switch实现分支判断
go提供了 switch 语句,它可以将单个值和多个值进行比较。
1 |
|
switch 语句的另一种用法是像 if…else 那样,在每个分支中单独设置比较条件。
switch 还拥有独特的 fallthrough
关键字,它可以用于执行下一个分支的代码。
与 c 和 java 等编程语言不同,go的 switch 语句执行一个条件分支后默认是不执行下一行的
1 |
|
使用循环实现重复执行
当需要重复执行同一段代码的时候,与一遍又一遍键入相同的代码相比,更好的办法是使用 for 关键字。
go语言是没有 while 循环关键字的,不过如下所示我们可以通过 for 关键字实现 while 循环。
后面会讲解 for 关键字如何实现类似于C语言中的那种形式。
1 |
|
在每次迭代开始之前,表达式 count>0 都会被求值并产生一个布尔值。当该值为 false也就是 count 变量等于 0 的时候,循环就会终止。反之,如果该值为真,那么程序将继续执行循环体,也就是被 { 和 } 包围的那部分代码。
此外我们还可以通过不为 for 语句设置任何条件来产生无限循环,然后在有需要的时候通过在循环体内使用 break 语句来跳出循环。
1 |
|
变量作用域
审视作用域
变量从声明之时开始就处于作用域当中,换句话说,变量就是从那时开始变为可见的。
只要变量仍然存在于作用域当中,程序就可以访问它。然而在作用域之外访问变量就会报错。
变量作用域的一个好处是我们可以为不同的变量复用相同的名字。因为除极少数小型程序之外,程序的变量几乎不可能不出现重名。
go 的作用域通常会随着大括号 {} 的出现而开启和结束。
在下面的代码清单中,main函数开启了一个作用域,而for循环则开启了一个嵌套作用域
1 |
|
因为对 count 变量的声明用于 main 函数的函数作用域之内,所以它在 main 函数结束之前将一致可见
在循环结束之后访问num变量将会引发编译器报错。
简短声明
简短声明为 var 关键字提供了另一种备选语法。
以下两行代码是完全等效的:
1 |
|
简短声明不仅仅是简化了声明语句,而且可以在无法使用 var 关键字的地方使用。
如下例代码
未使用简短声明
1 |
|
在不使用简短声明的情况下,count 变量的声明必须被放置在循环之外,这意味着在循环解释之后 count 变量将继续存在于作用域。
在for循环中使用简短声明
1 |
|
简短声明还可以在 if 语句中声明新的变量
1 |
|
在switch语句中使用
1 |
|
作用域的范围
1 |
|
因为对 era 变量的声明位于 main 函数之外的包作用域中,所以它对于 main 包中的所有函数都是可见的。
注意:因为包作用域在声明变量时不允许使用简短声明,所以我们无法在这个作用域中使用
后言
参考书籍:Go语言趣学指南
参考课程:Go语言编程快速入门(Golang)