NotePublic/Software/Development/Language/Go/Package/Go_包的创建和使用.md

144 lines
3.6 KiB
Markdown
Raw Normal View History

# Go 包的创建和使用
## 1.创建包
```go
/**
* @file demo/pkg/pkg.go
*/
package pkg
// ...
```
## 2.导入和使用包
```go
/**
* @file demo/main.go
*/
package main
import (
// 相对于当前路径
"demo/pkg"
// 在 $GOPATH 下
"my.com/mypkg"
)
func main() {
// ...
}
// ...
```
### 2.1.相对路径导入
导入当前文件同一目录的 model 包:
```go
import "./model"
```
### 2.2.绝对路径
加载 $GOPATH/src/shorturl/model 模块:
```go
import "shorturl/model"
```
### 2.3.“\.”操作
有时候会看到如下的方式导入包:
```go
import ( . "fmt" )
```
这个“\.”操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的:
```go
fmt.Println("hello world")
```
可以省略的写成:
```go
Println("hello world")
```
### 2.4.别名
别名操作顾名思义可以把包命名成另一个用起来容易记忆的名字:
```go
import ( f "fmt" )
```
别名操作调用包函数时前缀变成了重命名的前缀,即:
```go
f.Println("hello world")
```
### 2.5.“\_”操作
这个操作经常是让很多人费解的一个操作符,请看下面这个 import
```go
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
```
“\_”操作其实只是引入该包。当导入一个包时它所有的 init() 函数就会被执行,但有些时候并非真的需要使用这些包,仅仅是希望它的 init() 函数被执行而已。这个时候就可以使用“\_”操作引用该包了。即使用“\_”操作引用包是无法通过包名来调用包中的导出函数而是只是为了简单的调用其 init() 函数。
## 3. 使用 Go 包的常见问题
### 3.1. Why does go get fail with "invalid version: unknown revision"?
#### 问
I published an update to a Go module, bumping the version to v1.1.0. I created a tag named v1.1.0 and pushed the tag to GitHub.
https://github.com/depp/bytesize/releases/tag/v1.1.0
However, I cannot use this package in my other projects. I get an error that says, "invalid version: unknown revision v1.1.0". I don't know why the revision is "unknown", since it's tagged.
```bash
$ go get github.com/depp/bytesize@v1.1.0
go: downloading github.com/depp/bytesize v1.1.0
go get github.com/depp/bytesize@v1.1.0: github.com/depp/bytesize@v1.1.0: verifying module: github.com/depp/bytesize@v1.1.0: reading https://sum.golang.org/lookup/github.com/depp/bytesize@v1.1.0: 410 Gone
server response: not found: github.com/depp/bytesize@v1.1.0: invalid version: unknown revision v1.1.0
[Exit: 1]
```
#### 答
The tag was pushed after invoking go get once, which poisoned the Go module proxy cache.
From <https://proxy.golang.org/>:
Note that if someone requested the version before the tag was pushed, it may take up to 30 minutes for the mirror's cache to expire and fresh data about the version to become available.
The way to work around this before the cache expires is to use the GOPRIVATE environment variable to instruct go get to fetch this module directly, bypassing the cache.
From <https://golang.org/cmd/go/>:
GOPRIVATE, GONOPROXY, GONOSUMDB
Comma-separated list of glob patterns (in the syntax of Go's path.Match) of module path prefixes that should always be fetched directly or that should not be compared against the checksum database.
The workaround is:
```bash
$ GOPRIVATE=github.com/depp/bytesize go get github.com/depp/bytesize@v1.1.0
```
Note that if you are already using GOPRIVATE, you will want to add modules rather than overriding the value completely.