Go语言学习06~07 错误处理和包管理

Go语言学习06-错误处理

Go的错误机制

与其他主要编程语言的差异

  1. 没有异常机制

  2. error类型实现了error接口

  3. 可以通过 errors.New 来快速创建错误实例

    go 复制代码
    type error interface {
        Error() string
    }
    
    errors.New("n must be in range [0, 10]")

最佳实践

定义不同的错误变量, 以便于判断错误类型

go 复制代码
var LessThanTwoError = errors.New("n should be not less than 2")
var LargeThanHundredError = errors.New("n should be not larger than 100")

func GetFibonacci(n int) ([]int, error) {
	if n < 2 {
		return nil, LessThanTwoError
	}
	if n > 100 {
		return nil, LargeThanHundredError
	}
	fibList := []int{1, 1}

	for i := 2; i < n; i++ {
		fibList = append(fibList, fibList[i-2]+fibList[i-1])
	}
	return fibList, nil
}
func TestGetFibonacci(t *testing.T) {
	if v, err := GetFibonacci(-10); err != nil {
		if err == LessThanTwoError {
			fmt.Println("It is less.")
		}
		t.Error(err)
	} else {
		t.Log(v)
	}
}

及早失败, 避免嵌套!

panic

  • panic 用于不可恢复的错误
  • panic 退出前会执行 defer 指定的内容
panic vs. os.Exit
  • os.Exit 退出时不会调用 defer 指定的函数
  • os.Exit 退出时不输出当前调用栈信息

recover

go 复制代码
// 最常见的"错误恢复"
defer func() {
	if err := recover(); err != nil {
        Log.Error("recovered panic", err)
	}
}()

缺陷:

  • 形成僵尸服务进程, 导致 health check 失效
  • "Let it Crash!" 往往是我们恢复不确定性错误的最好方法


Go语言学习07-包和依赖管理

package

  1. 基本复用模块单元

    以首字母大写来表明可被包外代码访问

  2. 代码的 package 可以和所在的目录不一致

  3. 同一目录里的 Go 代码的 package 要保持一致


  1. 通过 go get 来获取远程依赖

    go get -u 强制从网络更新远程依赖

  2. 注意代码在 GitHub 上的组织形式, 以适应 go get

    直接以代码路径开始, 不要有 src

init 方法

  • 在 main 被执行前, 所有依赖的 package 的 init 方法都会被执行
  • 不同包的 init 函数按照包导入的依赖关系决定执行顺序
  • 每个包可以有多个init函数
  • 包的每个源文件也可以有多个init函数, 这点比较特殊

Go 未解决的依赖问题

  1. 统一环境下, 不同项目使用同一包的不同版本
  2. 无法管理对包的特定版本的依赖

vendor 路径

随着Go 1.5 release 版本的发布, vendor目录被添加到除了GOPATH 和GOROOT之外的依赖目录查找的解决方案。在Go 1.6之前,你需要手动的设置环境变量

查找依赖包路径的解决方案如下:

  1. 当前包下的 vendor 目录
  2. 向上级目录查找, 知道找到 src 下的 vendor 目录
  3. 在 GOPATH 下面查找依赖包
  4. 在 GOROOT 目录下查找

常用的依赖管理工具

godep https://github.com/tools/godep

glide https://github.com/Masterminds/glide

dep https://github.com/golang/dep

相关推荐
microrain9 小时前
读数是 1008,用电量是 8:SagooIoT 计算服务的增量口径与七种计算策略
物联网·golang·计算服务·sagooiot
看浪的路人11 小时前
第7讲:大模型后端服务化——Go 实现高并发 LLM Proxy / Router / Fallback
开发语言·后端·golang
灯澜忆梦14 小时前
【Go Zap 日志库】#1 |快速上手 + 配置详解
开发语言·后端·golang
不是万能的豆学长16 小时前
排查Go服务40天后的内存泄漏问题
开发语言·后端·golang·go
tachibana217 小时前
Go 语言 Map 的底层实现原理
开发语言·后端·golang·make
tachibana218 小时前
Go语言里slice是怎么扩容的?
后端·golang·go·切片
西瓜很甜哟18 小时前
golang实现大文件分片上传
后端·golang·html
tachibana21 天前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
王中阳Go1 天前
Go 后端转 AI:非科班怎么补?一张 3 列路线表(可保存)
开发语言·人工智能·后端·python·golang·大语言模型
for_ever_love__2 天前
LangChain Agentic RAG:让 Agent 自己决定要不要检索、检索几次
人工智能·golang·langchain·rag·langgraph·agentic·自适应检索