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 ⛅

相关推荐
追逐时光者1 小时前
精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具
后端·.net
TF男孩1 小时前
ARQ:一款低成本的消息队列,实现每秒万级吞吐
后端·python·消息队列
AAA修煤气灶刘哥2 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥2 小时前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
你的人类朋友3 小时前
什么是API签名?
前端·后端·安全
昵称为空C5 小时前
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
spring boot·后端
架构师沉默5 小时前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
RoyLin6 小时前
TypeScript设计模式:适配器模式
前端·后端·node.js
该用户已不存在6 小时前
Mojo vs Python vs Rust: 2025年搞AI,该学哪个?
后端·python·rust
Moonbit6 小时前
MoonBit 正式加入 WebAssembly Component Model 官方文档 !
前端·后端·编程语言