2026-01-24-Go语言基础语法

文章发布时间:

最后更新时间:

页面浏览: 加载中...

Go语言基础语法

简介

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型编程语言。Go语言语法简洁、易于学习,特别适合构建高并发、高性能的网络应用。

1. 变量与常量

变量声明

Go语言有多种声明变量的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 方式1:标准声明
var name string = "Go语言"
var age int = 10

// 方式2:类型推断
var name = "Go语言"
var age = 10

// 方式3:短变量声明(只能在函数内使用)
name := "Go语言"
age := 10

// 方式4:批量声明
var (
name string = "Go语言"
age int = 10
)

零值

变量声明后如果没有赋值,会自动赋为零值:

  • 数值类型:0
  • 字符串:空字符串 “”
  • 布尔值:false
  • 指针、切片、映射、函数、接口、通道:nil

常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 使用 const 关键字声明
const PI = 3.1415926
const GREETING = "Hello, Go!"

// 批量声明
const (
StatusOK = 200
StatusNotFound = 404
StatusError = 500
)

// iota 枚举(从0开始)
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)

2. 基本数据类型

数值类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 整型
var i int = 42 // 根据系统决定32位或64位
var i8 int8 = 127 // -128 到 127
var i16 int16 = 32767 // -32768 到 32767
var i32 int32 = 2147483647 // -2147483648 到 2147483647
var i64 int64 = 9223372036854775807
var u uint = 42 // 无符号整数
var u8 uint8 = 255 // 0 到 255
var u32 uint32 = 4294967295
var u64 uint64 = 18446744073709551615

// 浮点型
var f32 float32 = 3.14
var f64 float64 = 3.141592653589793

// 复数
var c64 complex64 = 3 + 4i
var c128 complex128 = 1 + 2i

字符串类型

1
2
3
var s string = "Hello, World!"
var r rune = '中' // Unicode字符,等价于int32
var b byte = 'A' // 等价于uint8

布尔类型

1
2
var isTrue bool = true
var isFalse bool = false

类型转换

1
2
3
4
5
6
7
8
var i int = 42
var f float64 = float64(i)

var s string = "42"
// 字符串转数字需要使用 strconv 包
import "strconv"
num, _ := strconv.Atoi(s)
num64, _ := strconv.ParseInt(s, 10, 64)

3. 运算符

算术运算符

1
2
3
4
5
6
7
8
a := 10
b := 3

fmt.Println(a + b) // 加法:13
fmt.Println(a - b) // 减法:7
fmt.Println(a * b) // 乘法:30
fmt.Println(a / b) // 除法:3(整数除法)
fmt.Println(a % b) // 取模:1

关系运算符

1
2
3
4
5
6
7
8
9
a := 10
b := 5

fmt.Println(a == b) // false
fmt.Println(a != b) // true
fmt.Println(a > b) // true
fmt.Println(a < b) // false
fmt.Println(a >= b) // true
fmt.Println(a <= b) // false

逻辑运算符

1
2
3
4
5
6
a := true
b := false

fmt.Println(a && b) // 逻辑与:false
fmt.Println(a || b) // 逻辑或:true
fmt.Println(!a) // 逻辑非:false

位运算符

1
2
3
4
5
6
7
8
a := 5  // 二进制:101
b := 3 // 二进制:011

fmt.Println(a & b) // 按位与:001 (1)
fmt.Println(a | b) // 按位或:111 (7)
fmt.Println(a ^ b) // 按位异或:110 (6)
fmt.Println(a << 1) // 左移:1010 (10)
fmt.Println(a >> 1) // 右移:010 (2)

4. 控制流

if-else 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 基本用法
age := 18
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}

// 带初始化语句
if age := 18; age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}

switch 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 基本 switch
day := 3
switch day {
case 1:
fmt.Println("周一")
case 2:
fmt.Println("周二")
case 3:
fmt.Println("周三")
default:
fmt.Println("其他")
}

// 多个条件
score := 85
switch {
case score >= 90:
fmt.Println("优秀")
case score >= 80:
fmt.Println("良好")
case score >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}

// fallthrough 继续执行下一个 case
num := 1
switch num {
case 1:
fmt.Println("one")
fallthrough
case 2:
fmt.Println("two") // 也会执行
}

for 循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 标准 for 循环
for i := 0; i < 10; i++ {
fmt.Println(i)
}

// 类似 while 循环
i := 0
for i < 10 {
fmt.Println(i)
i++
}

// 无限循环
for {
// 需要通过 break 退出
if i > 10 {
break
}
i++
}

// range 遍历
// 遍历数组/切片
nums := []int{1, 2, 3, 4, 5}
for index, value := range nums {
fmt.Printf("索引: %d, 值: %d\n", index, value)
}

// 遍历 map
m := map[string]int{"a": 1, "b": 2}
for key, value := range m {
fmt.Printf("键: %s, 值: %d\n", key, value)
}

// 遍历字符串
for index, char := range "Hello" {
fmt.Printf("索引: %d, 字符: %c\n", index, char)
}

break 和 continue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// break 跳出循环
for i := 0; i < 10; i++ {
if i == 5 {
break // 跳出循环
}
fmt.Println(i)
}

// continue 跳过当前迭代
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // 跳过偶数
}
fmt.Println(i) // 只打印奇数
}

goto 语句

1
2
3
4
5
6
7
8
for i := 0; i < 10; i++ {
if i == 5 {
goto end // 跳转到标签
}
fmt.Println(i)
}
end: // 标签
fmt.Println("循环结束")

5. 函数

函数定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 基本函数
func greet(name string) string {
return "Hello, " + name
}

// 多个返回值
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除数不能为0")
}
return a / b, nil
}

// 命名返回值
func calculate(a, b int) (sum int, product int) {
sum = a + b
product = a * b
return // 自动返回 sum 和 product
}

// 可变参数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}

// 匿名函数
result := func(a, b int) int {
return a + b
}(10, 20)

函数作为值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 函数作为参数
func applyOperation(a, b int, operation func(int, int) int) int {
return operation(a, b)
}

add := func(a, b int) int {
return a + b
}

result := applyOperation(10, 20, add) // 30

// 函数作为返回值
func makeAdder(x int) func(int) int {
return func(y int) int {
return x + y
}
}

add10 := makeAdder(10)
fmt.Println(add10(5)) // 15

6. 数组与切片

数组

1
2
3
4
5
6
7
8
// 数组声明(固定长度)
var arr1 [5]int // 零值数组
arr2 := [5]int{1, 2, 3, 4, 5} // 初始化
arr3 := [...]int{1, 2, 3, 4, 5} // 自动推断长度

// 访问元素
fmt.Println(arr2[0]) // 1
arr2[0] = 10

切片(Slice)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 切片声明(动态长度)
var s1 []int // nil 切片
s2 := []int{1, 2, 3, 4, 5} // 初始化切片
s3 := make([]int, 5) // 创建长度为5的切片
s4 := make([]int, 5, 10) // 创建长度为5、容量为10的切片

// 切片操作
s2 = append(s2, 6, 7, 8) // 添加元素
s2 = append(s2, s3...) // 合并切片

// 切片截取
sub := s2[1:4] // 索引1到3(不包括4)
fmt.Println(sub) // [2 3 4]

// 切片属性
fmt.Println(len(s2)) // 长度
fmt.Println(cap(s2)) // 容量

// 复制切片
s5 := make([]int, len(s2))
copy(s5, s2)

7. 映射(Map)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 创建 map
m1 := make(map[string]int)
m2 := map[string]int{"a": 1, "b": 2}

// 添加和修改
m1["a"] = 1
m1["b"] = 2

// 读取
value := m1["a"]
value, exists := m1["c"] // 检查键是否存在
if exists {
fmt.Println("键存在:", value)
} else {
fmt.Println("键不存在")
}

// 删除
delete(m1, "a")

// 遍历
for key, value := range m1 {
fmt.Printf("%s: %d\n", key, value)
}

8. 指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 指针声明
var p *int

// 获取指针
num := 42
p = &num // p 指向 num 的地址

// 通过指针访问值
fmt.Println(*p) // 42

// 通过指针修改值
*p = 100
fmt.Println(num) // 100

// 指针作为函数参数
func increment(num *int) {
*num++
}

n := 10
increment(&n)
fmt.Println(n) // 11

9. 结构体(Struct)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 定义结构体
type Person struct {
Name string
Age int
Address string
}

// 创建结构体
p1 := Person{"张三", 18, "北京"}
p2 := Person{Name: "李四", Age: 20}
p3 := &Person{Name: "王五", Age: 22} // 指针类型

// 访问字段
fmt.Println(p1.Name)
fmt.Println(p2.Age)
fmt.Println(p3.Address)

// 结构体方法
func (p Person) SayHello() {
fmt.Printf("你好,我是 %s\n", p.Name)
}

func (p *Person) HaveBirthday() {
p.Age++
}

p1.SayHello() // 你好,我是 张三
p1.HaveBirthday() // 需要使用指针接收器修改

10. 接口(Interface)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 定义接口
type Speaker interface {
Speak() string
}

// 实现接口
type Dog struct {
Name string
}

func (d Dog) Speak() string {
return "汪汪"
}

type Cat struct {
Name string
}

func (c Cat) Speak() string {
return "喵喵"
}

// 使用接口
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}

dog := Dog{Name: "旺财"}
cat := Cat{Name: "咪咪"}

MakeSound(dog) // 汪汪
MakeSound(cat) // 喵喵

// 类型断言
var speaker Speaker = dog
if dog, ok := speaker.(Dog); ok {
fmt.Println("这是一只狗:", dog.Name)
}

11. 错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import "errors"

// 创建错误
err := errors.New("这是一个错误")

// fmt.Errorf 格式化错误
err = fmt.Errorf("错误: %s", "详细信息")

// 返回错误
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除数不能为0")
}
return a / b, nil
}

// 处理错误
result, err := divide(10, 0)
if err != nil {
fmt.Println("发生错误:", err)
} else {
fmt.Println("结果:", result)
}

// panic 和 recover
func safeDivide(a, b int) (result int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("捕获到 panic:", r)
}
}()

result = a / b
return
}

safeDivide(10, 0) // 捕获到 panic

12. 并发(Goroutine 和 Channel)

Goroutine

1
2
3
4
5
6
7
8
9
10
11
12
13
// 启动 goroutine
go func() {
fmt.Println("这是在 goroutine 中执行")
}()

// 等待 goroutine 完成
done := make(chan bool)
go func() {
fmt.Println("任务完成")
done <- true
}()

<-done // 等待

Channel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 创建 channel
ch := make(chan int) // 无缓冲 channel
ch := make(chan int, 10) // 带缓冲 channel

// 发送数据
go func() {
ch <- 42 // 发送
}()

// 接收数据
value := <-ch // 接收

// 关闭 channel
close(ch)

// range 遍历 channel
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for value := range ch {
fmt.Println(value)
}

// select 多路复用
select {
case value := <-ch1:
fmt.Println("从 ch1 接收:", value)
case ch2 <- value:
fmt.Println("发送到 ch2")
case <-time.After(time.Second):
fmt.Println("超时")
}

13. defer 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// defer 延迟执行,常用于资源清理
func readFile(filename string) (string, error) {
file, err := os.Open(filename)
if err != nil {
return "", err
}
defer file.Close() // 函数返回前执行

// 读取文件内容
// ...

return "文件内容", nil
}

// 多个 defer 按栈的顺序执行
func example() {
defer fmt.Println("3")
defer fmt.Println("2")
defer fmt.Println("1")
}
// 输出:1, 2, 3

14. 包管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 导入包
import (
"fmt" // 标准库
"net/http" // 标准库
"github.com/gin-gonic/gin" // 第三方包
)

// 导入带别名
import (
myfmt "myproject/mypackage"
)

// 使用
fmt.Println("Hello")
myfmt.Println("Hello")

15. main 函数

1
2
3
4
// 程序入口
func main() {
fmt.Println("Hello, Go!")
}

总结

Go语言基础语法要点:

  • 变量声明使用 var:=(短变量声明)
  • 使用 const 定义常量
  • 强类型,支持类型转换
  • 丰富的控制流语句(if、switch、for)
  • 支持多返回值函数
  • 数组、切片、映射、指针、结构体等数据结构
  • 接口实现隐式转换
  • 错误处理使用返回值
  • goroutine 和 channel 实现并发
  • defer 语句用于资源清理