Go 包的使用 作用域 大小写机制

前言

Go Modules是Go语言的包管理工具,提供简洁可靠的依赖管理,解决了GOPATH和vendor目录的问题,使项目依赖更清晰易管理。要启用go module支持首先要设置环境变量GO111MODULE,通过它可以开启或关闭模块支持,它有三个可选值:off、on、auto,默认值是auto。设置GO111MODULE=on之后就可以使用go module了,以后就没有必要在GOPATH中创建项目了,并且还能够很好的管理项目依赖的第三方包信息。

命令

  1. GO111MODULE=off 禁用模块支持,编译时会从GOPATH和vendor文件夹中查找包。
  2. GO111MODULE=on 启用模块支持,编译时会忽略GOPATH和vendor文件夹,只根据 go.mod下载依赖。
  3. GO111MODULE=auto 当项目在$GOPATH/src外且项目根目录有go.mod文件时,开启模块支持。
sh 复制代码
go env -w GO111MODULE=on 设置GO111MODULE
go env set GO111MODULE 查看GO111MODULE环境变量
go env 查看所有环境变量

使用

go的项目也是一个单独包 初始化一个项目,新建一个 demo文件夹,执行命令 go mod init demo 会生成一个 go.mod 文件 新建一个main.go 作为程序入口文件

sh 复制代码
└── demo
    ├── go.mod
    └── main.go
go 复制代码
package main

func main() {

}
yaml 复制代码
package main

func main() {
}

使用下载包

使用 go get 下载

go 复制代码
└── demo
    ├── utils
    │   └── hello.go
    ├── go.mod
    ├── go.sum
    └── main.go
sh 复制代码
go get go.uber.org/zap

在 main.go 中使用

go 复制代码
package main
import (
	"go.uber.org/zap"
)
func main() {
	zapLog, _ := zap.NewProduction()
	zapLog.Info("failed to fetch URL")
}

go.mod

yaml 复制代码
module demo

go 1.19

require (
	go.uber.org/multierr v1.10.0 // indirect
	go.uber.org/zap v1.27.0 // indirect
)

require 引用依赖包及版本 indirect 表示间接引用

导入项目子文件的包

新建 utils 文件夹和 hello.go文件

go 复制代码
└── demo
    ├── utils
    │   └── hello.go
    ├── go.mod
    ├── go.sum
    └── main.go

hello.go 内容

go 复制代码
package utils

import "fmt"

func Hello() {
	fmt.Println("hello world")
}

在main中使用

go 复制代码
package main
import "main/utils"
func main() {
	pkg2.Hello()
}

导入本地包

demo 同级目录下创建一个 pkg 包

go 复制代码
├── demo
│   ├── utils
│   │   └── hello.go
│   ├── go.mod
│   ├── go.sum
│   └── main.go  
└── pkg
    ├── go.mod
    └── hello.go
  1. 初始化pkg包 go mod init pkg
  2. 在 pkg2 目录新建 hello.go文件
go 复制代码
package pkg

import "fmt"

func PkgHello() {
	fmt.Println("PkgHello:hello world")
}
  1. 在 demo main里面调用
go 复制代码
package main

import "pkg2" 

func main() {
	pkg2.Hello()
}

你会发现报错 could not import pkg2 (no required module provides package "pkg2")因为这两个包不在同一个项目路径下,你想要导入本地包,并且这些包也没有发布到远程的github或其他代码仓库地址。这个时候我们就需要在go.mod文件中使用replace指令。

  1. 修改pkg1下的go.mod文件
sh 复制代码
module demo

go 1.19

require (
	go.uber.org/multierr v1.10.0 // indirect
	go.uber.org/zap v1.27.0 // indirect
	pkg2 v0.0.0
)

replace pkg2 => ../pkg2

go run main.go 运行是否正常

  • replace 替换包的地址

注意

注意需要引入的函数和变量首字母需要大写 封装机制 包是不能互相引入的就会形成循环导入go语言是禁止的

Go 语言的封装机制大小写机制

如果以大写字母开头,表示该标识符是公开的,可以被其他包引用 如果以小写字母开头,表示该标识符是私有的,只能在定义它的包中使用,其他包无法直接引用 变量命 函数名 类型名 属性名 都需要需要遵循

go 复制代码
var One = 1
var two = 2
func OneFn(){}
func twoFn(){}
type OneType struct {
    Name string  // 公开字段
    age  int     // 私有字段
}
type twoType struct {
    Name string  // 公开字段
    age  int     // 私有字段
}

One OneFn OneType 可以被引用 但是OneType中的age字段不能正常使用 u := pkg.OneType{Name: "xx"} 小写的为私有只能在定义它们的包中使用

作用域

go 复制代码
package main

import "fmt"

// 包级作用域 全局作用域 区别在于是不是主文件
var globalVar = "This is a global variable"

func main() {
    // 函数级作用域
    var localVar = "This is a local variable"

    // 块级作用域
    {
        blockVar := "This is a block variable"
        fmt.Println(localVar) // 可以访问函数级作用域内的变量
        fmt.Println(blockVar) // 可以访问块级作用域内的变量
    }

    fmt.Println(globalVar) // 可以访问包级作用域内的变量
    // fmt.Println(blockVar) // 编译错误,无法访问块级作用域外的变量
}

扩展

熟悉 go module 的命令

sh 复制代码
go mod help        展示所有命令
go mod download    下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录)
go mod edit        编辑go.mod文件 (--fmt 格式化)
go mod graph       打印模块依赖图
go mod init        初始化当前文件夹, 创建go.mod文件
go mod tidy        增加缺少的module,删除无用的module
go mod vendor      将依赖复制到vendor下
go mod verify      校验依赖
go mod why         解释为什么需要依赖

熟悉 go mod 文件的一些关键字

  1. module 用来定义包名
  2. go 1.19 当前go的版本
  3. require 用来定义依赖包及版本
  4. indirect 表示间接引用
  5. replace 替换包的地址

包下载 get get

使用下载包的前提是需要了解两个命令 go get go install go get命令可以下载依赖包,并且还可以指定下载的版本

  1. 运行go get -u将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
  2. 运行go get -u=patch将会升级到最新的修订版本
  3. 运行go get package@version将会升级到指定的版本号version

2024/3/5 ⛅

相关推荐
加油,旭杏2 小时前
【go语言】接口
开发语言·后端·golang
谢大旭2 小时前
ASP.NET Core 中间件
后端·中间件·c#
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS景区民宿预约系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
HelloDam4 小时前
基于 mzt-biz-log 实现接口调用日志记录
后端
SomeB1oody5 小时前
【Rust自学】15.6. RefCell与内部可变性:“摆脱”安全性限制
开发语言·后端·rust
兮动人7 小时前
Golang 执行流程分析
开发语言·后端·golang·golang 执行流程分析
码农小旋风8 小时前
如何自己设计一个类似 Dubbo 的 RPC 框架?
后端
拾忆,想起9 小时前
如何选择Spring AOP的动态代理?JDK与CGLIB的适用场景
spring boot·后端·spring·spring cloud·微服务
zhuyasen9 小时前
多维度详细比较 kratos、go-zero、goframe、sponge 框架
后端·http·微服务·rpc·golang