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 ⛅

相关推荐
CryptoPP9 分钟前
springboot 对接马来西亚数据源API等多个国家的数据源
spring boot·后端·python·金融·区块链
Source.Liu23 分钟前
【学Rust写CAD】27 双线性插值函数(bilinear_interpolation.rs)
后端·rust·cad
yinhezhanshen27 分钟前
理解rust里面的copy和clone
开发语言·后端·rust
uhakadotcom34 分钟前
Helm 简介与实践指南
后端·面试·github
栗筝i1 小时前
Spring 核心技术解析【纯干货版】- XIX:Spring 日志模块 Spring-Jcl 模块精讲
java·后端·spring
企鹅不耐热.1 小时前
Scala基础知识6
开发语言·后端·scala
程序员一诺1 小时前
【Django开发】前后端分离django美多商城项目第15篇:商品搜索,1. Haystack介绍和安装配置【附代码文档】
后端·python·django·框架
冷琅辞2 小时前
Go语言的嵌入式网络
开发语言·后端·golang
跟着珅聪学java4 小时前
spring boot +Elment UI 上传文件教程
java·spring boot·后端·ui·elementui·vue
徐小黑ACG5 小时前
GO语言 使用protobuf
开发语言·后端·golang·protobuf