• go使用第三方包和本地包_小小郭-程序员宅基地_go引入第三方包


    前言

    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
  • 相关阅读:
    nginx1.9+新增tcp/udp代理stream
    mysql授权
    搭建GIT服务器
    Centos调出图形化的网络管理
    吾爱破解论坛纪念壁纸(怀念)
    VNC-tigervnc-server远程调用图形化
    Linux生成高强度密码
    Linux学习必备
    git编译
    书单
  • 原文地址:https://www.cnblogs.com/lidabo/p/15193030.html
Copyright © 2020-2023  润新知