Files
MyBlog/src/programming/backend/go/go基础入门.md
2025-12-15 23:16:59 +08:00

12 KiB
Raw Blame History

icon, date, category, tag, star
icon date category tag star
mdi:language-go 2025-05-22
后端开发
Go语言
Go
编程语言
入门教程
true

Go 语言基础入门

Go又称 Golang是由 Google 开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。它于 2009 年首次发布,以其简洁、高效和强大的并发处理能力而闻名。

目录

  1. Go 语言简介
  2. 环境搭建
  3. 第一个 Go 程序
  4. 基本语法
  5. 数据类型
  6. 变量和常量
  7. 运算符
  8. 控制结构
  9. 函数
  10. 数组和切片
  11. 映射(Map)
  12. 结构体
  13. 接口
  14. 并发编程
  15. 错误处理
  16. 包管理

Go 语言简介

Go 语言的设计目标是:

  • 简单易学:语法简洁,去除了许多其他语言的复杂特性
  • 高效执行:编译型语言,运行速度快
  • 内置并发支持:通过 goroutine 和 channel 实现轻量级并发
  • 强大的标准库:提供了丰富的内置库
  • 跨平台支持:支持多种操作系统和架构

环境搭建

下载安装

  1. 访问 Go 官方网站 下载适合你操作系统的安装包
  2. Windows 用户下载 .msi 文件macOS 用户下载 .pkg 文件Linux 用户下载 .tar.gz 文件

Windows 安装步骤

  1. 双击下载的 .msi 文件开始安装
  2. 默认会安装到 C:\Go\ 目录下
  3. 安装完成后会自动配置环境变量

Linux 安装步骤

# 下载 Go 安装包
wget https://golang.org/dl/go1.19.linux-amd64.tar.gz

# 解压到 /usr/local 目录
sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz

# 配置环境变量
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc

验证安装

打开终端或命令提示符,输入以下命令验证是否安装成功:

go version

如果显示版本信息,则说明安装成功。

设置工作目录

Go 项目推荐使用模块化管理,在任意目录下创建你的项目文件夹:

mkdir myproject
cd myproject
go mod init myproject

第一个 Go 程序

创建一个名为 main.go 的文件:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

运行程序:

go run main.go

或者编译后运行:

go build main.go
./main

代码解释:

  • package main:声明这是一个可执行程序的主包
  • import "fmt":导入格式化输入输出包
  • func main():程序入口函数
  • fmt.Println():打印文本并换行

基本语法

注释

// 单行注释

/*
多行注释
可以跨越多行
*/

标识符命名规则

  • 只能包含字母、数字和下划线
  • 不能以数字开头
  • 区分大小写
  • 不能是关键字

关键字

Go 语言有 25 个关键字:

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

数据类型

Go 语言的数据类型分为四大类:

基本类型

  1. 布尔型booltrue/false
  2. 数字类型
    • 整数型int8, int16, int32, int64, uint8, uint16, uint32, uint64, int, uint, uintptr
    • 浮点型float32, float64
    • 复数型complex64, complex128
  3. 字符串类型string
  4. 派生类型
    • 指针类型Pointer
    • 数组类型
    • 结构化类型struct
    • Channel 类型
    • 函数类型
    • 切片类型
    • 接口类型interface
    • Map 类型

类型示例

var a bool = true              // 布尔型
var b int = 10                 // 整型
var c float32 = 3.14           // 浮点型
var d string = "Hello"         // 字符串
var e complex64 = 3+4i         // 复数型

变量和常量

变量声明

四种声明变量的方式:

// 1. 指定变量类型,声明后若不赋值则使用默认值
var v1 int

// 2. 根据值自行判定变量类型
var v2 = 10

// 3. 省略 var注意 := 左侧的变量必须是未声明过的
v3 := 10

// 4. 多变量声明
var v4, v5 int = 1, 2
var v6, v7 = 3, "hello"
v8, v9 := 5, true

变量作用域

  • 局部变量:在函数内声明,只在函数内有效
  • 全局变量:在函数外声明,在整个包内有效

常量声明

const PI = 3.14159
const NAME = "Golang"

// 常量组
const (
    Monday = 1
    Tuesday = 2
    Wednesday = 3
)

iota

iota 是一个特殊的常量,用于生成一组相似的常量值:

const (
    a = iota   // 0
    b          // 1
    c          // 2
    d          // 3
)

运算符

算术运算符

运算符 描述
+ 相加
- 相减
* 相乘
/ 相除
% 求余
++ 自增
-- 自减

关系运算符

运算符 描述
== 相等
!= 不相等
> 大于
< 小于
>= 大于等于
<= 小于等于

逻辑运算符

运算符 描述
&& 逻辑与
|| 逻辑或
! 逻辑非

位运算符

运算符 描述
& 按位与
| 按位或
^ 按位异或
<< 左移
>> 右移

控制结构

条件语句 if

if condition {
    // code
}

// 带初始化语句
if x := 10; x > 5 {
    fmt.Println("x 大于 5")
} else {
    fmt.Println("x 小于等于 5")
}

循环语句 for

Go 只有一种循环结构for 循环

// 基本 for 循环
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// while 形式的循环
i := 0
for i < 10 {
    fmt.Println(i)
    i++
}

// 无限循环
for {
    // 死循环
}

选择语句 switch

switch day {
case 1:
    fmt.Println("Monday")
case 2:
    fmt.Println("Tuesday")
default:
    fmt.Println("Unknown day")
}

// 不带条件的 switch
switch {
case score >= 90:
    fmt.Println("优秀")
case score >= 80:
    fmt.Println("良好")
default:
    fmt.Println("一般")
}

函数

函数定义

func functionName(parameterName type) returnType {
    // 函数体
    return returnValue
}

示例

// 简单函数
func add(a int, b int) int {
    return a + b
}

// 多返回值函数
func swap(x, y string) (string, string) {
    return y, x
}

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

函数调用

result := add(3, 5)
a, b := swap("hello", "world")
total := sum(1, 2, 3, 4, 5)

defer 语句

defer 用于延迟执行函数,通常用于资源清理:

func readFile() {
    file, err := os.Open("file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close() // 函数结束前关闭文件
    
    // 处理文件...
}

数组和切片

数组

数组是固定长度的序列:

// 声明数组
var arr1 [5]int                    // 长度为 5 的整型数组
arr2 := [5]int{1, 2, 3, 4, 5}     // 初始化数组
arr3 := [...]int{1, 2, 3}         // 根据元素个数确定长度

// 访问数组元素
fmt.Println(arr2[0])              // 输出 1
arr2[1] = 10                      // 修改元素

切片

切片是对数组的抽象,长度可变:

// 创建切片
slice1 := []int{1, 2, 3}          // 直接创建切片
slice2 := make([]int, 5)          // 创建长度为 5 的切片
slice3 := make([]int, 3, 5)       // 长度为 3容量为 5

// 从数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
slice4 := arr[1:4]                // 包含索引 1 到 3 的元素

// 切片操作
slice5 := append(slice1, 4, 5)    // 添加元素
len(slice1)                       // 获取长度
cap(slice1)                       // 获取容量

映射(Map)

Map 是一种无序的键值对集合:

// 创建 map
var m1 map[string]int             // 声明但未初始化
m2 := make(map[string]int)        // 使用 make 初始化
m3 := map[string]int{             // 直接初始化
    "apple":  5,
    "banana": 3,
}

// 操作 map
m2["orange"] = 10                 // 添加键值对
value := m2["orange"]             // 获取值
delete(m2, "orange")              // 删除键值对

// 检查键是否存在
if val, ok := m2["apple"]; ok {
    fmt.Println("apple:", val)
} else {
    fmt.Println("apple not found")
}

结构体

结构体是一种用户自定义的数据类型,允许我们组合不同类型的字段:

// 定义结构体
type Person struct {
    Name    string
    Age     int
    Email   string
}

// 创建结构体实例
person1 := Person{Name: "张三", Age: 25, Email: "zhangsan@example.com"}
person2 := Person{"李四", 30, "lisi@example.com"}
person3 := Person{}  // 所有字段使用零值

// 访问结构体字段
fmt.Println(person1.Name)
person1.Age = 26

// 结构体指针
person4 := &Person{Name: "王五", Age: 28}
fmt.Println(person4.Name)  // 自动解引用

方法

方法是带有接收者的函数:

// 为结构体定义方法
func (p Person) SayHello() {
    fmt.Printf("Hello, I'm %s\n", p.Name)
}

func (p *Person) SetAge(age int) {
    p.Age = age
}

// 调用方法
person1.SayHello()
person1.SetAge(27)

接口

接口是一组方法签名的集合:

// 定义接口
type Shape interface {
    Area() float64
    Perimeter() float64
}

// 实现接口
type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}

// 使用接口
var s Shape = Rectangle{Width: 10, Height: 5}
fmt.Println("Area:", s.Area())
fmt.Println("Perimeter:", s.Perimeter())

并发编程

Go 语言内置了强大的并发支持,主要包括 goroutine 和 channel。

Goroutine

Goroutine 是轻量级线程:

// 启动 goroutine
go func() {
    fmt.Println("Hello from goroutine")
}()

// 启动多个 goroutine
for i := 0; i < 5; i++ {
    go func(n int) {
        fmt.Printf("Goroutine %d\n", n)
    }(i)
}

Channel

Channel 用于 goroutine 之间通信:

// 创建 channel
ch := make(chan int)

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

// 从 channel 接收数据
value := <-ch
fmt.Println(value)

// 带缓冲的 channel
bufferedCh := make(chan int, 3)
bufferedCh <- 1
bufferedCh <- 2
bufferedCh <- 3

Select

Select 用于在多个 channel 操作中进行选择:

select {
case msg1 := <-ch1:
    fmt.Println("Received", msg1)
case msg2 := <-ch2:
    fmt.Println("Received", msg2)
case <-time.After(time.Second):
    fmt.Println("Timeout")
}

错误处理

Go 语言通过返回错误值来进行错误处理:

// 错误处理示例
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

// 使用错误
result, err := divide(10, 0)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

自定义错误

type MyError struct {
    Msg string
    Code int
}

func (e *MyError) Error() string {
    return fmt.Sprintf("Error %d: %s", e.Code, e.Msg)
}

包管理

创建模块

go mod init myproject

添加依赖

go get github.com/gin-gonic/gin

查看依赖

go mod tidy
go list -m all

go.mod 文件示例

module myproject

go 1.19

require (
    github.com/gin-gonic/gin v1.8.1
)

总结

Go 语言以其简洁的语法、强大的并发支持和高效的执行性能成为现代软件开发的重要选择。通过本文档的学习,你应该掌握了 Go 语言的基本概念和语法,可以开始编写简单的 Go 程序了。

建议接下来的学习路径:

  1. 练习更多 Go 语言编程题目
  2. 学习标准库的使用
  3. 了解 Go 语言的最佳实践
  4. 尝试构建实际项目

Happy coding with Go!