1. 安装和配置Go环境
- 安装Go:访问Go官网下载对应操作系统的安装包,并按照指引完成安装。
- 配置环境变量:确保
GOPATH
和GOROOT
环境变量已正确设置。可在命令行中输入go version进行检查。 - 豆包MarsCode IDE:在豆包MarsCode中可以创建云上的虚拟环境,更快启动项目进行学习与测试。
2.Go程序基本框架
我们以Hello world为例子概述go程序的结构,首先导入一个包package main
,package main
是一个包声明语句,用于表明当前 Go 源文件所属的包名。在 Go 语言里,代码是通过包(package)来组织和模块化管理的。所有的 Go 代码都必须属于某个包,包就像是代码的容器,把相关的类型、函数、变量等元素组织在一起,方便复用、维护以及代码的逻辑划分。
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
Go语言可以导入其他的 Go 包来使用它们提供的功能,同时其他包也可以被其他项目中的不同包复用。使用import
关键字导入相关包,其中fmt
包用于格式化输入输出,go应用程序的函数主体为func main
,是程序的主入口即程序代码开始执行的地方,上面的示例程序会输出一行“Hello world”。
3.Go语言的编译和运行
-
使用
go build
命令编译:- 这是最常用的编译方式。在命令行中,进入包含 Go 源文件(通常是
package main
文件)的目录,然后执行go build
命令。例如,如果你的 Go 源文件名为main.go
,执行go build
后,会在当前目录下生成一个可执行文件(在 Linux 和 macOS 下默认没有文件扩展名,在 Windows 下是.exe
文件)。如果项目中有多个源文件,go build
会自动查找并编译所有相关的文件。
- 这是最常用的编译方式。在命令行中,进入包含 Go 源文件(通常是
-
使用
go run
命令编译并执行:- 当你只是想快速测试一段 Go 代码时,可以使用
go run
命令。例如,go run main.go
会先编译main.go
文件(以及它所依赖的其他文件),然后立即执行生成的可执行文件。这种方式不会在当前目录下留下编译后的可执行文件,适合用于开发过程中的快速验证。
- 当你只是想快速测试一段 Go 代码时,可以使用
-
跨平台编译:
- Go 语言支持跨平台编译。通过设置环境变量
GOOS
(目标操作系统)和GOARCH
(目标架构),可以在一个平台上编译出用于其他平台的可执行文件。例如,要在 Linux 平台上编译一个用于 Windows 的可执行文件,可以执行GOOS = windows GOARCH = amd64 go build
命令。
- Go 语言支持跨平台编译。通过设置环境变量
4.变量的声明与定义
var age int
var name string = "John"
var a,b,c int
var x,y,z = 1,"two",true
age := 25
a,b := 1,2
-
变量声明
-
单一变量声明:
- 在 Go 语言中,使用
var
关键字来声明变量。例如,var age int
声明了一个名为age
的整数类型变量。此时变量被声明,但还没有初始化,它会被赋予该类型的零值。对于整数类型,零值是0
。 - 也可以在声明变量的同时进行初始化,如
var name string = "John"
,这里声明了一个名为name
的字符串变量,并初始化为"John"
。
- 在 Go 语言中,使用
-
多个变量声明:
- 可以使用
var
一次声明多个变量,变量之间用逗号隔开。例如,var a, b, c int
声明了三个整数类型变量a
、b
和c
,它们的初始值都是0
。 - 也可以在声明多个变量时进行不同的初始化,如
var x, y, z = 1, "two", true
,这里x
被初始化为1
(类型为整数),y
被初始化为"two"
(类型为字符串),z
被初始化为true
(类型为布尔值)。Go 语言会根据初始化的值自动推断变量的类型。
- 可以使用
-
-
变量定义(简短变量声明)
- Go 语言提供了简短变量声明的方式,使用
:=
操作符。例如,age := 25
,这里不仅声明了变量age
,还同nil:在 Go 语言中,nil
是一个特殊的值,用于表示指针、接口、映射(map)、切片(slice)和通道(channel)等类型的零值或未初始化状态。例如,对于指针类型,当声明一个指针变量但未对其赋值时,它的值为nil
。这里,i := 0
是初始化语句,用于初始化循环变量i
;i < 5
是条件表达式,只要这个条件为真,循环就会继续;i++
是后置语句,在每次循环体执行完后执行,通常用于更新循环变量。这个循环会输出0
到4
。
- Go 语言提供了简短变量声明的方式,使用
for - range
循环(用于遍历容器类型) :在Go语言中,for - range
循环用于遍历数组、切片、字符串、映射(map)等容器类型。例如,遍历切片:
slice := []string{"apple", "banana", "cherry"}
for index, value := range slice {
println(index, value)
}
这里,index
表示元素的索引(对于数组、切片等),value
表示元素的值。在每次循环中,index
和value
会被更新为下一个元素的索引和值。对于映射,index
表示键(key),value
表示值。如果只需要值,可以使用for _, value := range slice
的形式,其中_
表示忽略索引。
- 分支结构
if - else语句
num :=9
if num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
上述代码中首先声明并创建了一个整体变量num
并赋值为9,其不满足第一个if
分支,往下检查发现满足if-else
分支,那么就执行此代码块,如果不满足则执行else
分支里面的代码块。
switch语句
switch
语句用于多分支选择。基本形式为switch
表达式 { case值1: 执行代码块1; case值2: 执行代码块2;... default: 执行代码块n }。例如:
day := 3
switch day {
case 1:
println("星期一")
case 2:
println("星期二")
case 3:
println("星期三")
//...
default:
println("其他")
}
当switch
后面的表达式(这里是day
)的值与某个case
后面的值匹配时,就会执行对应的代码块。如果没有匹配的case
,就会执行default
代码块(default
部分是可选的)。
6.数组,slice,映射MAP
数组
-
定义与初始化:
- 在 Go 语言中,数组是具有固定长度的同类型元素的序列。定义数组时需要指定元素类型和数组长度。例如,
var numbers [5]int
定义了一个包含 5 个整数元素的数组,数组中的元素初始值为 0(因为int
类型的零值是 0)。 - 也可以在定义数组时进行初始化,如
var fruits = [3]string{"apple", "banana", "cherry"}
,这里定义了一个长度为 3 的字符串数组,并初始化为三个水果名称。
- 在 Go 语言中,数组是具有固定长度的同类型元素的序列。定义数组时需要指定元素类型和数组长度。例如,
-
访问元素:
- 通过索引来访问数组中的元素,索引从 0 开始。例如,对于上面定义的
numbers
数组,numbers[0]
表示访问第一个元素,numbers[4]
表示访问最后一个元素。可以对数组元素进行读取和赋值操作,如numbers[2] = 10
,将数组中索引为 2 的元素赋值为 10。
- 通过索引来访问数组中的元素,索引从 0 开始。例如,对于上面定义的
-
数组的长度:
- 使用
len()
函数来获取数组的长度。例如,对于fruits
数组,len(fruits)
会返回 3。数组的长度是其类型的一部分,这意味着[3]int
和[5]int
是不同的类型,不能直接相互赋值。
- 使用
-
数组的遍历:
- 可以使用
for
循环来遍历数组。例如:
- 可以使用
for i := 0; i < len(numbers); i++ {
println(numbers[i])
}
也可以使用for - range
循环来遍历数组,这种方式更加简洁,并且在不需要索引时可以忽略索引变量。例如:
for _, number := range numbers {
println(number)
}
切片(Slice)
-
定义与初始化:
- 切片是对数组的一个引用片段,它本身不存储数据,而是通过引用底层数组来提供数据访问。可以通过多种方式创建切片。例如,从数组创建切片:
numbers := [5]int{1, 2, 3, 4, 5}
,slice := numbers[1:4]
,这里slice
是一个切片,它引用了numbers
数组中索引从 1(包含)到 4(不包含)的元素,即{2, 3, 4}
。 - 还可以使用
make
函数来创建切片,如slice := make([]int, 3, 5)
,这创建了一个int
类型的切片,长度为 3(即切片中当前有 3 个元素),容量为 5(切片底层数组的长度为 5,容量决定了切片可以扩展的最大长度)。
- 切片是对数组的一个引用片段,它本身不存储数据,而是通过引用底层数组来提供数据访问。可以通过多种方式创建切片。例如,从数组创建切片:
-
访问元素和修改元素:
- 切片元素的访问方式和数组类似,通过索引访问。例如,对于上面创建的
slice
,slice[0]
访问第一个元素。可以对切片元素进行修改,修改会反映到底层数组中。例如,slice[1] = 10
会修改切片中的第二个元素,同时也会修改底层数组中对应的元素。
- 切片元素的访问方式和数组类似,通过索引访问。例如,对于上面创建的
-
切片的长度和容量:
- 切片的长度可以使用
len()
函数获取,容量可以使用cap()
函数获取。例如,对于slice := make([]int, 3, 5)
,len(slice)
返回 3,cap(slice)
返回 5。切片的长度小于等于容量,当切片长度小于容量时,可以通过append
操作来添加新元素,直到切片长度达到容量。
- 切片的长度可以使用
-
切片的操作:
append
操作:用于向切片添加新元素。例如,slice = append(slice, 6)
会在切片末尾添加一个元素 6。如果切片的长度达到容量,append
操作会自动分配一个更大的底层数组,并将原来的数据复制过去。copy
操作:用于将一个切片中的元素复制到另一个切片中。例如,slice1 := []int{1, 2, 3}
,slice2 := make([]int, 3)
,copy(slice2, slice1)
会将slice1
中的元素复制到slice2
中。- 切片的切片(子切片) :可以从一个切片中再创建子切片,方式和从数组创建切片类似。例如,
slice := []int{1, 2, 3, 4, 5}
,subSlice := slice[1:4]
,这里subSlice
是slice
的一个子切片,包含{2, 3, 4}
。
映射(Map)
-
定义与初始化:
- 映射(在其他编程语言中也称为字典、哈希表等)是一种无序的键 - 值对(key - value)数据结构。在 Go 语言中,使用
map
关键字来定义映射。例如,var ages map[string]int
声明了一个映射,键是字符串类型,值是整数类型,但此时这个映射还没有初始化,它的值是nil
,不能直接使用,需要使用make
函数进行初始化,如ages = make(map[string]int)
。 - 也可以在定义映射时进行初始化,如
students := map[string]int{"Alice": 20, "Bob": 22}
,这里创建了一个键为学生名字(字符串),值为学生年龄(整数)的映射,并初始化为两个学生的信息。
- 映射(在其他编程语言中也称为字典、哈希表等)是一种无序的键 - 值对(key - value)数据结构。在 Go 语言中,使用
-
访问和修改元素:
- 通过键来访问映射中的值。例如,对于
students
映射,students["Alice"]
可以获取Alice
对应的年龄。如果键不存在,会返回值类型的零值。可以通过赋值来修改映射中的值,如students["Alice"] = 21
,修改Alice
对应的年龄为 21。
- 通过键来访问映射中的值。例如,对于
-
元素的插入和删除:
- 插入元素可以通过赋值操作实现,如
students["Charlie"] = 23
,在students
映射中插入一个新的学生Charlie
的年龄信息。删除元素可以使用delete
函数,如delete(students, "Bob")
,会删除students
映射中键为Bob
的元素。
- 插入元素可以通过赋值操作实现,如
-
映射的遍历:
- 使用
for - range
循环来遍历映射。例如:
- 使用
for key, value := range students {
println(key, value)
}
7.函数与返回值
- 函数定义 ◦ 在 Go 语言中,函数使用
func
关键字来定义。函数定义的基本格式为func 函数名(参数列表) 返回值类型 { 函数体 }
。例如,func add(num1, num2 int) int { return num1 + num2 }
定义了一个名为add
的函数,它接受两个整数参数num1
和num2
,并返回它们的和,返回值类型也是整数。 ◦ 函数名遵循 Go 语言的标识符命名规则,参数列表中的参数可以是不同类型的变量,多个参数之间用逗号隔开。如果函数没有参数,参数列表可以为空,如func printHello() { println("Hello") }
。 - 返回值 在Go语言中,函数的返回值可以有多个,比如如下的例子
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
多个返回值的定义在函数名和形参后面的括号内进行声明即可,这时候调用者会获得多个返回值。