💜 想真正擅长编程? 从一门课程开始,100% 免费

《笔记》第十一篇 包测试

第11讲 包测试

本讲义根据视频实际讲解内容整理

一、本讲概述

本讲讲解了 Go 语言中包(Package)和文件的概念。大项目不可能只用一个文件,需要通过包来实现模块化、封装和代码重用。老师演示了如何创建包、导入包,以及包的导出规则、作用域、多返回值等知识点。


二、为什么需要包

"大的项目,肯定不可能是一个文件玩吧。"

  • 之前所有代码都写在一个文件中
  • 大项目需要分层、分目录管理代码
  • 包(Package)的目的:支持模块化、封装、单独编译和代码重用
  • 类似于 Java 中的包和模块

三、包的基本概念

3.1 包的源文件

  • 一个包的源代码保存在一个或多个 .go 后缀的文件中
  • 通常一个包所在的目录路径就是包的导入路径

3.2 独立的命名空间

  • 每个包对应一个独立的名字空间
  • 例如,unicode 包中的 Decode 和其他包中的 Decode 是不同的
  • 外部引用时需要通过 包名.函数名 的方式访问

3.3 导出规则(核心)

"如果一个名字是大写字母开头的,那么该名字是可导出的。"

首字母 可见性 说明
大写 可导出(公开) 外部包可以访问
小写 不可导出(私有) 仅包内部可访问

四、创建和导入包

4.1 创建包

老师在课堂上演示了创建一个自定义包:

Go
// 目录结构
// myproject/
//   main.go
//   utils/
//     utils.go

// utils/utils.go
package utils

func Add(a int, b int) int {  // 大写开头,可导出
    return a + b
}

func helper() {  // 小写开头,不可导出
    // 仅包内可用
}

4.2 导入包

Go
// main.go
package main

import (
    "fmt"
    "myproject/utils"  // 导入自定义包
)

func main() {
    result := utils.Add(3, 5)  // 通过 包名.函数名 调用
    fmt.Println(result)        // 8
}

4.3 老师演示中遇到的问题

老师在演示时遇到了一些实际问题:

  1. 包名大小写问题:包名统一用小写,不要大写
  2. 版本差异问题:Go 模块路径需要正确配置,有时需要在 go.mod 中加上模块名
  3. go mod 管理:使用 go mod init 初始化模块

五、包的初始化

5.1 初始化顺序

"包的初始化,首先是解决包变量的依赖程序,第一个初始化,第二个初始化,第三个初始化。"

  • 包初始化时,会先解决变量依赖关系
  • 按照依赖顺序依次初始化

5.2 子包的创建

老师演示了在包下面再创建子包:

TEXT
myproject/
  main.go
  utils/
    utils.go
  utils/sub/
    sub.go

六、作用域(Scope)

6.1 := 的使用限制

老师重点讲解了一个容易出错的地方:

":=(短变量声明)能不能写到函数外面呢?不能!"

Go
package main

import "fmt"

var a int = 10  // ✅ 函数外用 var 声明,正确

// b := 20  // ❌ 函数外不能用 :=,编译错误

func main() {
    a = 10
    fmt.Println(a)  // 10

    b := 20         // ✅ 函数内可以用 :=
    fmt.Println(b)  // 20
}

6.2 作用域规则总结

位置 声明方式 说明
函数内 := 或 var 都可以
函数外(包级) 只能用 var 不能用 :=

"在外面我们不能用这种方式(:=),必须用 var 的形式,在里面就没事。"


七、多返回值与下划线

7.1 函数返回多个值

老师演示了 Go 函数可以返回多个值:

Go
package main

import "fmt"

func calculate(a int, b int) (int, int) {
    return a + b, a - b
}

func main() {
    sum, diff := calculate(10, 3)
    fmt.Println("和:", sum)   // 和: 13
    fmt.Println("差:", diff)  // 差: 7
}

7.2 用下划线忽略返回值

如果不需要某个返回值,用 _(下划线)忽略:

Go
sum, _ := calculate(10, 3)  // 只需要和,忽略差
fmt.Println("和:", sum)      // 和: 13

"下划线就是把结果给它省略了,不需要的值用下划线表示。"

7.3 函数声明格式

老师强调了函数声明的格式:

Go
func 函数名(参数列表) (返回类型) {
    // 函数体
}
  • 参数类型在参数名后面
  • 返回类型在参数列表后面
  • 多返回值用括号包裹

八、后续内容预告

老师在讲义末尾提到了后续将要学习的内容:

类别 内容
基本数据类型 整数、浮点数等
复合数据类型 数组、切片、Map
结构体和 JSON 后续使用较多
函数 递归、多返回值

"结构体和 JSON 可能用得比较多。"


九、小结

本讲涵盖了包和文件的核心知识:

  1. 包的作用:模块化、封装、代码重用
  2. 导出规则:大写字母开头 = 可导出,小写 = 私有
  3. 创建和导入包:通过目录组织包,用 import 导入
  4. 作用域::= 只能在函数内使用,函数外必须用 var
  5. 多返回值:Go 支持函数返回多个值,用 _ 忽略不需要的值