Go 基础知识
最后修改时间 2024 年 4 月 11 日
本文介绍 Go 语言的基本编程概念。
Go 是一种开源编程语言,可以轻松构建简单、可靠且高效的软件。Go 是一种由 Google 创建的静态类型、编译型编程语言。
标识符
标识符是变量、函数、类或参数的名称。标识符可以包含字母数字字符和下划线。变量名不能以数字开头。名称中不允许使用空格。
标识符是区分大小写的。这意味着 Name、name 和 NAME 指的是三个不同的变量。标识符也不能与语言关键字冲突。
Go 空白符
Go 中的空白符用于分隔程序中的标记。它也用于提高源代码的可读性。
var i int = 0
在某些地方需要空白符。例如,在 i 变量和 int 关键字之间。在其他地方,禁止使用空白符。它们不能出现在变量标识符或语言关键字中。
var i int=1 var j int = 2 var k int = 3
标记之间的空格量对于 Go 编译器无关紧要。应在 Go 程序中一致使用空格。
第一个示例
我们创建第一个示例。
$ mkdir first $ cd first
我们创建一个项目目录并切换到那里。
$ go mod init zetcode.com/first
我们初始化一个 Go 模块。
package main
import "fmt"
func main() {
fmt.Println("Go first example")
}
这是一个简单的 Go 程序,它将消息打印到控制台。
package main
Go 代码组织在包中。程序在 main 包中开始运行。
import "fmt"
使用 import 关键字将包包含到程序中。fmt 包包含具有格式化 I/O 的函数。
func main() {
在 main 包中,main 函数是 Go 程序的入口点。使用 func 关键字创建函数。
fmt.Println("Go first example")
从 fmt 包中,我们使用 Println 函数显示消息。请注意,语句不像 Java、C 或 C# 等语言那样以分号结尾。
$ go run main.go Go first example
我们使用 go run 命令一次性编译和执行程序。
注释
注释用于人类来澄清源代码。Go 中有两种类型的注释:单行注释(//)和多行注释(/* */)。
package main
import "fmt"
/*
This is comments.go
Author: Jan Bodnar
ZetCode 2024
*/
// Program starts here
func main() {
fmt.Println("Go first example")
}
在代码示例中,我们有一个多行注释和一个单行注释。编译器会忽略注释。
变量
变量用于存储值。它是给值的标签。Go 使用 var 关键字来声明变量列表。我们也可以使用 := 简写语法来声明变量。
变量可以保存不同数据类型的值。数据类型是一组值以及对这些值允许的操作。在许多情况下,Go 可以从赋值的右侧推断出数据类型。
package main
import "fmt"
func main() {
var i int = 1
var w float64 = 12.5
fmt.Println(i, w)
}
在代码示例中,我们声明并初始化了两个变量,然后打印它们。第一个变量存储一个整数,第二个变量存储一个浮点数。在 Go 中,数据类型跟在变量名后面。
类型推断
Go 可以从赋值的右侧推断出数据类型。
package main
import (
"fmt"
"reflect"
)
func main() {
var name = "John Doe"
var age = 34
fmt.Println(reflect.TypeOf(name))
fmt.Println(reflect.TypeOf(age))
fmt.Printf("%s is %d years old\n", name, age)
}
在代码示例中,我们定义了两个变量而没有指定它们的数据类型。数据类型是推断出来的。
var name = "John Doe" var age = 34
为了让推断起作用,变量必须初始化。
fmt.Println(reflect.TypeOf(name)) fmt.Println(reflect.TypeOf(age))
借助 reflect 包中的 TypeOf 函数,我们打印出两个变量的数据类型。
$ go run main.go string int John Doe is 34 years old
简写变量声明
在函数内部,可以使用 := 简短赋值语句代替带有隐式类型的 var 声明。
package main
import "fmt"
func main() {
name := "John Doe"
age := 34
fmt.Println("%s is %d years old", name, age)
}
该示例使用简写表示法声明了两个变量。
用户输入
Scanf 函数读取标准输入中的文本,并根据格式将连续的空格分隔的值存储到连续的参数中。它返回成功扫描的项目数。
package main
import "fmt"
func main() {
var name string
fmt.Print("Enter your name: ")
fmt.Scanf("%s", &name)
fmt.Println("Hello", name)
}
该示例提示用户输入名字。
var name string
我们定义一个字符串变量。
fmt.Scanf("%s", &name)
输入的价值被存储在 name 变量中。
$ go run main.go Enter your name: Robert Hello Robert
我们运行程序并输入一个名字。
条件语句
条件语句使用 if、else if 和 else 关键字创建。
package main
import (
"fmt"
"math/rand"
)
func main() {
num := -5 + rand.Intn(10)
if num > 0 {
fmt.Println("The number is positive")
} else if num == 0 {
fmt.Println("The number is zero")
} else {
fmt.Println("The number is negative")
}
}
在本例中,我们生成一个介于 -5 和 4 之间的随机值。借助条件语句,我们为所有三个选项打印一条消息。
for 循环
for 语句指定块的重复执行。
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
这是经典的 C 风格 for 语句。该程序计算 1..9 的值之和。
for i := 0; i < 10; i++ {
sum += i
}
for 语句包含三个部分:初始化、条件和增量。初始化部分仅执行一次。当条件为真时,执行 for 语句的主体。如果条件返回 false,则 for 循环终止。
在执行完块中的语句后,for 循环会进入第三部分,其中计数器会增加。循环继续,直到条件不再为真。请注意,可能创建无限循环。
$ go run main.go 45
1..9 的值之和为 45。
以下示例使用带 range 关键字的 for 循环。
package main
import "fmt"
func main() {
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println(sum)
}
该示例计算数组值的总和。
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
我们定义了一个值数组。
for _, num := range nums {
sum += num
}
我们使用 range 子句迭代数组。range 在每次迭代中返回索引和值。由于我们不使用索引,我们指定了丢弃符 _。(Go 文档称之为空白标识符。)
Switch 语句
Go switch 语句提供多路执行。将表达式或类型说明符与 switch 中的 case 进行比较,以确定执行哪个分支。与其他语言(如 C、Java 或 PHP)不同,每个 case 都由隐式的 break 终止;因此,我们不必显式编写它。
default 语句可用于在没有其他 case 匹配时执行的分支。default 语句是可选的。
package main
import (
"fmt"
"runtime"
)
func main() {
os := runtime.GOOS
switch os {
case "windows":
fmt.Println("Windows")
case "darwin":
fmt.Println("MAC operating system")
case "linux":
fmt.Println("Linux")
default:
fmt.Printf("%s.\n", os)
}
}
GOOS 环境变量是正在运行的程序的操作系统目标:可能是 darwin、freebsd、linux 等。根据变量的值,我们打印操作系统版本。
$ go run main.go Linux
命令行参数
命令行参数是传递给程序的选项和数据。我们通常将参数传递给控制台程序,但有时也传递给 GUI 程序。
os.Args 包含命令行参数。此切片中的第一个值是程序名称,而 os.Args[1:] 包含传递给程序的参数。可以通过索引操作访问各个参数。
package main
import (
"fmt"
"os"
"reflect"
)
func main() {
prg_name := os.Args[0]
fmt.Printf("The program name is %s\n", prg_name)
names := os.Args[1:]
fmt.Println(reflect.TypeOf(names))
for _, name := range names {
fmt.Printf("Hello, %s!\n", name)
}
}
该示例接收命令行参数。
prg_name := os.Args[0]
fmt.Printf("The program name is %s\n", prg_name)
我们获取并打印第一个参数,即程序名称。
names := os.Args[1:]
我们获取所有接收到的参数。
fmt.Println(reflect.TypeOf(names))
我们打印持有参数的类型(切片)。
for _, name := range names {
fmt.Printf("Hello, %s!\n", name)
}
我们遍历参数并从每个参数构建一条消息。
$ go build main.go $ ./main Jan Peter Lucia The program name is main []string Hello, Jan! Hello, Peter! Hello, Lucia!
我们构建程序并运行它。我们在命令行上传递了三个名字给程序。
函数
函数是将零个或多个输入参数映射到零个或多个输出参数。Go 函数是头等公民。函数可以赋值给变量、作为参数传递给函数或从函数返回。
Go 中的函数使用 func 关键字创建。我们使用 return 关键字从函数返回。函数体包含函数调用时执行的语句。函数体用一对花括号 {} 分隔。要调用函数,我们指定其名称后跟圆括号 ()。函数可以接受参数,也可以不接受参数。
package main
import "fmt"
func main() {
x := 4
y := 5
z := add(x, y)
fmt.Printf("Output: %d\n", z)
}
func add(a int, b int) int {
return a + b
}
在代码示例中,我们定义了一个将两个值相加的函数。
z := add(x, y)
我们调用 add 函数;它接受两个参数。计算出的值传递给 z 变量。
func add(a int, b int) int {
return a + b
}
我们定义 add 函数。函数参数用逗号分隔;每个参数名后跟其数据类型。在参数之后,我们指定返回值类型。调用函数时执行的语句放在花括号之间。加法操作的结果使用 return 关键字返回给调用者。
$ go run main.go Output: 9
来源
The Go Programming Language Specification
本文介绍了 Go 语言的基础知识。