Go语言实践[回顾]教程05--深入实践第一个Go语言示例
解读第一个Go语言示例代码
学过编程语言的都有一个印象,就是大部分编程语言都有一个 Hello World 示例代码,以最直观最易懂的方式,让初学者体验到该语言的魅力。Go 语言也不例外,在 LiteIDE 上创建一个新项目时,就会自动创建一个 Hello World 示例代码。下面我们就以这个示例项目代码逐步展开,深入实践。
示例代码的需求
启动程序后,在控制台输出 Hello World! 字符串,然后退出程序。
示例源代码
// test01 project main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
示例代码解读
Go 语言代码语句的结尾可以不写分号。
● 第1行代码:代码注释
// 是单行注释标记符,Go 语言支持单行注释和区块注释 /* */。应用方式与常用的开发语言基本一致。
● 第2行代码:声明 main 包
package:是包名声明的关键字,必须放在该文件的最顶部(前面可以有注释);
main:是包名,一个Go 语言项目里只能且必需有一个 main 包,否则不能正常编译。这一行作用是声明此文件内的代码是属于 main 包内的代码。示例中是将这个文件保存为 main.go,其实文件名可以不是main,但是为了方便理解和维护,通常还是建议将包含 main 函数的代码文件命名为 main.go 为好。
● 第4~6行代码:导入 fmt 包
import:是导入包的关键字。示例中是带括号的多行语法,可以用一个关键字导入多个包,每个包名占一行。也可以 import “fmt” 这样单行语法,推荐使用多行语法。
fmt:是要导入的包名,标准库中的格式化输出包。
● 第8~10行代码:声明创建一个 main 函数
func:是声明定义函数的关键字;
main:是函数名;main 函数是Go语言程序的入口函数,也就是程序启动后第一个运行的函数。main 函数只能声明在 main 包中,且 main 包里必需有一个 main 函数。
():是用于声明参数的,如果没有参数则留空。
{:是函数体代码段起始界定符,必须与函数名在同一行,否则编译时会报错。
fmt.Println():是调用执行 fmt 包里的 Println 格式化输出函数。可以打印输出字符串、整数、小数等。
“Hello World!”:要打印输出的字符串,用双引号包上就表示是字符串字面量。
}:是函数体代码段结束界定符,单独占一行。
更改需求继续实践示例代码
经过上面的解读,对 Go 语言有个初步的印象,有其他编程语言基础的同学们,肯定此时还有很多基础类的疑问。那接下来我们就改变需求,看代码该如何变化,从中体验 Go 语言的语法、规则、技巧等,逐步将 Go 语言编程应用到实际的项目需求中。
更改项目需求为动态输出时间
启动程序后,在控制台输出 Now is 2022-09-19 15:39:58 字符串(日期时间是当时系统的实际时间,这里只是举例显示格式),然后退出程序。
更改后示例源代码解读(使用全局变量)
// test01 project main.go
package main
import (
"fmt"
"time"
)
var now string
func main() {
now = time.Now().Format("2006-01-02 15:04:05")
fmt.Println("Now is", now)
}
● 较上一示例增加了第6行,因为需要获取系统时间,所以需要导入标准库中的 time 包;
导入多个包时,每个包占一行即可,不需要逗号分割。第4~7行这种导入文件的写法是被官方推荐的写法,虽然也可以分两行分别写成 import “fmt” 和 import “time”,但是经过Go 语言代码格式化工具后还是会变回现在的格式。另外不支持单行导入用逗号分割的格式。
● 增加了第9行,声明一个全局变量 now,类型是 string 字符串类型。
var 是声明变量的关键字,全局变量必须使用这个关键字;now 是变量名;string 是数据类型为字符串。在没有初始化赋值的情况下,Go 语言声明变量必须声明数据类型。与其他语言不同,Go 语言的类型关键字在变量名的后面。
● 增加了第12行,给字符串全局变量 now 在函数内赋值为当前系统日期时间。
Go 语言在函数内是可以直接使用全局变量的。 Now() 是 time 包中获取当前系统完整时间的函数,返回的是 time 类型;Format() 是格式化函数,返回的是字符串格式。Go强类型语言,若数据类型不一致是不能编译通过的。 Format 函数的参数 “2006-01-02 15:04:05” 具体含义如下:
含义 | 值 | 输出说明 |
---|---|---|
月份 | 1,01,Jan,January | 1:不补0的月;01:补0的月 |
日 | 2,02,_2 | 2:不补0的日;02:补0的日 |
时 | 3,03,15,PM,pm,AM,am | 3:不补0的时;03:补0的时;15:24小时制的时 |
分 | 4,04 | 4:不补0的分;04:补0的分 |
秒 | 5,05 | 5:不补0的秒;05:补0的秒 |
年 | 06,2006 | 06:两位数的年;2006:四位数的年 |
周几 | Mon,Monday | Mon:星期几的英文简写;Monday:星期几的完整单词 |
记忆技巧:6是年份,从1到5依次是月、日、时、分、秒。
● 修改了第13行,对 fmt.Println 函数的参数为两个,第一个是 “Now is” 字符串,第二个是 变量 now,也就是上面获取到的当前系统日期时间。
运行后输出:Now is 2022-09-19 22:00:39
使用全局变量初始化赋值的方式修改代码
// test01 project main.go
package main
import (
"fmt"
"time"
)
var now = time.Now().Format("2006-01-02 15:04:05")
func main() {
fmt.Println("Now is", now)
}
● 修改了第9行,在声明全局变量 now 时直接初始化赋值为当前系统时间。这样可以省略变量的类型声明,赋的值是什么类型,变量就会被声明成什么类型。
● 删除了原来的第12行,因为在声明变量的时已经赋完值了。
以上代码编译运行后,得到的输出是同样的结果。
使用局部变量初始化赋值的方式修改代码
// test01 project main.go
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Println("Now is", now)
}
这次代码改动就是取消了全局变量,因为我们只有在 main 函数内使用 now 变量,所以就可以在函数内声明一个局部变量。
● 第10行代码,是声明局部变量 now 同时初始化的代码。Go语言局部变量声明时直接初始化,可以简化掉 var 关键字和类型标识符,赋值运算符使用 := ,变量的类型就是赋值数据的类型,这样编写时就很简洁。
以上代码编译运行后,得到的输出是同样的结果。
不使用变量的方式修改代码
// test01 project main.go
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Now is", time.Now().Format("2006-01-02 15:04:05"))
}
这次代码改动没有使用任何变量。因为考虑只有在 fmt.Println() 函数的参数中才用到之前的 now 变量,其他任何地方没有再使用过 now 变量,那么就可以将给 now 初始化赋值的语句移动到 fmt.Println() 函数的参数中代替 now 即可。所以第10行代码中的 fmt.Println() 函数的第二个参数由 now 修改成 time.Now().Format(“2006-01-02 15:04:05”),删除变量声明。
以上代码编译运行后,得到的输出是同样的结果。
容易遇到的变量赋值错误
// test01 project main.go
package main
import (
"fmt"
"time"
)
var now string
now = time.Now().Format("2006-01-02 15:04:05")
func main() {
fmt.Println("Now is", now)
}
这段代码编译运行会报:“syntax error: non-declaration statement outside function body”。翻译过来就是:“语法错误:函数体外的非声明语句”。
Go 语言强调闭包,所以不允许在函数体外直接给变量赋值(初始化赋值例外)。这样第11行代码不在任何函数体内,所以会报错,将其移动到 main 函数体内就正常了。
本节小结
以下是对本节涉及的 Go 语言编程内容的归纳总结,方便记忆。
● 注释有单行注释 // 和 多行区块注释 /**/ 两种。
● 语句结尾不需要使用分号。
● 每个文件除注释外的第一行代码必须是包的声明,格式:package 包名。
● main 包是项目中必须有且只能有一个的包。
● 同一个文件夹下的 Go 源码文件必须属于同一个包,文件夹名可以与包名不同,但建议最好相同(main除外)便于理解维护。文件名与包名无关,编译时识别的是源码文件中的包名。
● 包是为了代码复用或逻辑清晰而设立的,可以理解为是一个功能模块。
● 导入模块使用 import (包名) 这种多行语法,每个包占一行,无需逗号分割。导入标准库中的包不需要带路径,只写包名即可。虽然还有其他写法,但官方格式化工具会最终格式化为这种语法格式,所以仅记住这一种即可。
● 声明定义函数必须使用 func 关键字,格式:func 函数名(参数) { },左花括号必须与函数名在同一行,参数及返回值后面再继续深入。
● main 函数必须在 main 包内,是项目程序启动运行的入口函数。一个项目必须且只能有一个 main 函数。
● 声明变量使用 var 关键字,全局变量必须有此关键字,声明格式:var 变量名 类型;全局变量声明时初始化赋值可以简化掉类型,格式:var 变量名 = 值;局部变量声明时直接初始化,还可以简化掉 var 关键字,格式:变量名 := 值。
● 全局变量声明后,禁止在函数体外进行直接赋值操作。
● fmt.Println() 是常用的打印输出函数,可以带多个参数,使用时记得导入 fmt 包。
● time.Now() 及 time.Now().Format() 是常用的日期时间操作函数,使用时记得引入 time 包。
.
.
上一节:Go/Golang语言学习实践[回顾]教程04–安装一个Go语言的集成开发环境