DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

前言

go之前对第三方包的管理不上心,其他语言比如python有pip,nodejs有npm,而go却没有一个官方的管理工具。

在go 1.11之前,开发者需要要关注GOPATH环境变量,这对于开发者来说不友好。

经过几次变更后,go于1.12版本开始正式使用go Module,go终于有了一个官方的处理方式,开发者也可以抛弃GOPATH了。

本次使用的go版本为1.15.6,建议使用1.13或以上的版本,旧的方式就不要再关注了,让它随风而去吧。

go version go1.15.6 darwin/amd64

本次使用的系统为Ubuntu,实验路径/opt/golang

root@xxg:/opt/golang# pwd
/opt/golang

第三方包

假设我们有个项目叫caseshow,我们先创建这个目录,并初始化一下

mkdir caseshow
cd caseshow
go mod init caseshow

此时在caseshow目录下会自动产生一个go.mod文件,内容如下:

module caseshow

go 1.15

比如我们想使用一个redis客户端:github.com/go-redis/redis/v8,在当前路径下直接执行go get命令即可:

go get github.com/go-redis/redis/v8

最近访问github很慢,可以先设置一下代理

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

设置好之后,下载第三方库

root@xxg:/opt/golang/caseshow# go get github.com/go-redis/redis/v8
go: downloading github.com/go-redis/redis v6.15.9+incompatible
go: downloading github.com/go-redis/redis/v8 v8.4.2
go: github.com/go-redis/redis/v8 upgrade => v8.4.2
go: downloading go.opentelemetry.io/otel v0.14.0
go: downloading github.com/cespare/xxhash/v2 v2.1.1
go: downloading github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f

目录下会多一个go.sum文件,go.mod文件里面也多了关于redis库的内容

root@xxg:/opt/golang/caseshow# ls
go.mod  go.sum
root@xxg:/opt/golang/caseshow# cat go.mod 
module caseshow

go 1.15

require github.com/go-redis/redis/v8 v8.4.2 // indirect

之后就可以直接用了,写个redis.go测试下:

package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
)

var ctx = context.Background()

func ExampleClient() {
    
	rdb := redis.NewClient(&redis.Options{
    
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	err := rdb.Set(ctx, "key", "value", 0).Err()
	if err != nil {
    
		panic(err)
	}

	val, err := rdb.Get(ctx, "key").Result()
	if err != nil {
    
		panic(err)
	}
	fmt.Println("key", val)

	val2, err := rdb.Get(ctx, "key2").Result()
	if err == redis.Nil {
    
		fmt.Println("key2 does not exist")
	} else if err != nil {
    
		panic(err)
	} else {
    
		fmt.Println("key2", val2)
	}
	// Output: key value
	// key2 does not exist
}

func main() {
    
	ExampleClient()
}

测试正常:

root@xxg:/opt/golang/caseshow# go run redis.go
key value
key2 does not exist

整个过程没有GOPATH什么事。

本地包

在项目开发中会复用本地的一些代码,这就涉及到了本地包的引入。

情况0 同路径引用其他文件

无需import,直接使用对应的方法。
go build时,在后面加上要用的文件名即可,比如

go build main.go main_command.go 

go run调试时,在后面加上要用的文件名即可,比如

go run main.go main_command.go 

情况1 同目录下

在同路径下不能存在多个package名,如果要定义其他的package,可以创建一个对应名字的目录,把代码放下面,之后再引用。
假设在caseshow中有个本地开发的包mymodule,里面有个方法Pprint,结构如下

# tree
.
├── go.mod
├── go.sum
├── mymodule
│   └── pprint.go
└── redis.go

1 directory, 4 files

pprint.go的代码如下:

package mymodule

import "fmt"

func Pprint(a string){
    
    fmt.Println("pprint ", a)
}

如果caseshow目录下的其他地方要用这个方法,则使用caseshow + package名称导入即可。
比如main.go:

package main

import "caseshow/mymodule"

func main(){
    
    mymodule.Pprint("jack")
}

直接运行:

# go run main.go 
pprint  jack

情况2 不同目录下

假设有另一个项目caselive,与caseshow同级,该目录下有个包yourmodule,里面有个方法Yprint:

# tree
.
├── caselive
│   ├── go.mod
│   ├── main.go
│   └── yourmodule
│       └── yprint.go
└── caseshow
    ├── go.mod
    ├── go.sum
    ├── main.go
    ├── mymodule
    │   └── pprint.go
    └── redis.go

4 directories, 8 files

yprint.go的内容如下:

package yourmodule

import "fmt"

func Yprint(a string){
    
    fmt.Println("yprint ", a)
}

此时在caseshow中要调用caselive中yourmodule的Yprint方法,可以用replace参数来实现。

在caseshow的go.mod中增加caselive的引入:

require mypackage v0.0.0
replace mypackage => ../mypackage

完整内容如下:

module caseshow

go 1.15

require github.com/go-redis/redis/v8 v8.4.2 // indirect
require caselive v0.0.0

replace caselive => ../caselive

之后就能直接调用了:

package main

import "caseshow/mymodule"
import "caselive/yourmodule"

func main(){
    
    mymodule.Pprint("jack")
    yourmodule.Yprint("jack")
}

运行测试下:

# go run main.go 
pprint  jack
yprint  jack
posted on   DoubleLi  阅读(508)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2019-08-27 使用Debug Diagnostic Tool排除内存泄漏故障
2014-08-27 [Boost]boost的时间和日期处理-(1)日期的操作
2014-08-27 [Boost]boost的时间和日期处理-(2)时间的操作
2013-08-27 c++一些面试题目
2013-08-27 C++类对应的内存结构
2013-08-27 windows窗口分析,父窗口,子窗口,所有者窗口
2013-08-27 mfc窗口,父窗口parentwindow,所有者窗口ownerwindow 区别
点击右上角即可分享
微信分享提示