golang之pkg(包)
一、概述
Golang拥有超过100个标准包(可用go list std |wc -l查看)
任何包系统设计的目的都是简化大型程序的设计和维护工作,通过将一组相关的特性放进一个独立的模块以便于理解和更新,在每个模块更新的同时保持和程序中其他模块的相对独立,这种模块化的特性允许每个包能被其他的不同项目共享和重用,在项目范围内、全局范围内的复用;
每个包一般都定义了一个不同的名字空间用于它内部的每个标识符的访问。 每个名字空间关联到一个特定的包, 让我们给类型、 函数等选择简短明了的名字, 这样可以避免在我们使用它们的时候减少和其它部分名字的冲突。
每个包还通过控制包内名字的可见性和是否导出来实现封装特性。 通过限制包成员的可见性并隐藏包API的具体实现, 将允许包的维护者在不影响外部包用户的前提下调整包的内部实现。 通过限制包内变量的可见性, 还可以强制用户通过某些特定函数来访问和更新内部变量, 这样可以保证
内部变量的一致性和并发时的互斥约束。
二、包的使用之导入路径
每个包是由一个全局唯一的字符串所标识的导入路径定位。 出现在import语句中的导入路径也是字符串。
import (
"fmt"
"math/rand"
"encoding/json"
"golang.org/x/net/html"
"github.com/go-sql-driver/mysql"
)
三、包声明:
在每个Go源文件的开头都必须有包声明语句。 包声明语句的主要目的是确定当前包被其它包导入时默认的标识符(也称为包名)
例如, math/rand包的每个源文件的开头都包含 package rand 包声明语句, 所以当你导入这个包, 你就可以用rand.Int、 rand.Float64类似的方式访问包的成员。
关于默认包名一般采用导入路径名的最后一段的约定也有三种例外情况。
第一个例外, 包对应一个可执行程序, 也就是main包, 这时候main包本身的导入路径是无关紧要的。 名字为main的包是给go build( §10.7.3) 构建命令一个信息, 这个包编译完之后必须调用连接器生成一个可执行程序。
第二个例外, 包所在的目录中可能有一些文件名是以test.go为后缀的Go源文件( 译注:前面必须有其它的字符, 因为以``前缀的源文件是被忽略的) , 并且这些源文件声明的包名也是以_test为后缀名的。 这种目录可以包含两种包:一种普通包, 加一种则是测试的外部扩展包。
所有以_test为后缀包名的测试外部扩展包都由go test命令独立编译, 普通包和测试的外部扩展包是相互独立的。 测试的外部扩展包一般用来避免测试代码中的循环导入依赖。
第三个例外, 一些依赖版本号的管理工具会在导入路径后追加版本号信息, 例如"gopkg.in/yaml.v2"。 这种情况下包的名字并不包含版本号后缀, 而是yaml。
warning:如果我们想同时导入两个有着名字相同的包, 例如math/rand包和crypto/rand包, 那么导入声明必须至少为一个同名包指定一个新的包名以避免冲突。 这叫做导入包的重命名。
import (
"crypto/rand"
mrand "math/rand" // alternative name mrand avoids conflict
)
warning:匿名导入:
import _ "image/png" // register PNG decoder
// The jpeg command reads a PNG image from the standard input
// and writes it as a JPEG image to the standard output.
package main
import (
"fmt"
"image"
"image/jpeg"
_ "image/png" // register PNG decoder
"io"
"os"
)
func main() {
if err := toJPEG(os.Stdin, os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "jpeg: %v\n", err)
os.Exit(1)
}
}
func toJPEG(in io.Reader, out io.Writer) error {
img, kind, err := image.Decode(in) //这里可能需要匿名导入
if err != nil {
return err
}
fmt.Fprintln(os.Stderr, "Input format =", kind)
return jpeg.Encode(out, img, &jpeg.Options{Quality: 95})
}
下面说说工作机制。 标准库还提供了GIF、 PNG和JPEG等格式图像的解码器,用户也可以提供自己的解码器, 但是为了保持程序体积较小, 很多解码器并没有被全部包含, 除非是明确需要支持的格式。 image.Decode函数在解码时会依次查询支持的格式列表。
每个格式驱动列表的每个入口指定了四件事情:格式的名称;一个用于描述这种图像数据开头部分模式的字符串, 用于解码器检测识别;一个Decode函数用于完成解码图像工作;一个DecodeConfig函数用于解码图像的大小和颜色空间的信息。 每个驱动入口是通过调用image.RegisterFormat函数注册, 一般是在每个格式包的init初始化函数中调用, 例如image/png包是这样注册的:
package png // image/png
func Decode(r io.Reader) (image.Image, error)
func DecodeConfig(r io.Reader) (image.Config, error)
func init() {
const pngHeader = "\x89PNG\r\n\x1a\n"
image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
}
最终的效果是, 主程序只需要匿名导入特定图像驱动包就可以用image.Decode解码对应格式的图像!
四、自定义自己的包:
包是函数和数据的集合。用 package 关键字定义一个包。文件名不需要与包名一致,但是你的文件夹必须要与包名字一致,这个很重要,所以为了简单起见,名字都是一样的。包名的约定是使用小写字符。Go 包可以由多个文件组成,但是使用相同的;
package 这一行。让我们在文件 test1.go 中定义一个叫做 pkg的包。
├── pkg
│ └── myprint.go //myprint.go
package pkg
import "fmt"
func MyPrintf(in string) {
fmt.Printf("%s", in)
}
在main包中测试:
package main
import (
"fmt"
"./pkg" //带上路径
) func main() {
pkg.MyPrinf("my pkg test")
fmt.Printf("test ok")
} //测试ok
稍作修改:
package main
import (
"fmt"
"pkg" //不带上路径
) func main() {
pkg.MyPrinf("my pkg test")
fmt.Printf("test ok")
} //closure.go:6:2: cannot find package "pkg" in any of:
/root/golang/go/src/pkg (from $GOROOT)
/root/src/pkg (from $GOPATH) # 解决办法:将pkg包加个软连接到$GOROOT 或$GOPATH
golang之pkg(包)的更多相关文章
- Golang爬虫示例包系列教程(一):pedaily.com投资界爬虫
Golang爬虫示例包 文件结构 自己用Golang原生包封装了一个爬虫库,源码见go get -u -v github.com/hunterhug/go_tool/spider ---- data ...
- 一键解决 go get golang.org/x 包失败
问题描述 当我们使用 go get.go install.go mod 等命令时,会自动下载相应的包或依赖包.但由于众所周知的原因,类似于 golang.org/x/... 的包会出现下载失败的情况. ...
- 19-03【golang】strings包
golang的strings包提供了字符串操作的一系列函数.下面做个简单介绍 函数 用法 备注 Compare(a,b sring) 比较两个字符串 Contains(s, substr stri ...
- 关于golang.org/x包问题
关于golang.org/x包问题 由于谷歌被墙,跟谷歌相关的模块无法通过go get来下载,解决方法: git clone https://github.com/golang/net.git $GO ...
- Golang Gin 项目包依赖管理 godep 使用
Golang Gin 项目包依赖管理 godep 使用 标签(空格分隔): Go 在按照github.com/tools/godep文档go get完包以后,调整项目结构为$GOPATH/src/$P ...
- golang 关于golang.org/x包问题
关于golang.org/x包问题 由于谷歌被墙,跟谷歌相关的模块无法通过go get来下载,解决方法: git clone https://github.com/golang/net.git $GO ...
- Golang的json包
encoding/json encoding/json是官方提供的标准json, 实现RFC 7159中定义的JSON编码和解码.使用的时候需要预定义struct,原理是通过reflection和in ...
- Golang官方log包详解
Golang官方log包详解 以下全是代码, 详解在注释中, 请从头到尾看 // Copyright 2009 The Go Authors. All rights reserved. // Use ...
- 下了个pkg包的jenkins,的使用方法
三.如何启动Jenkins1.最简单的方法是双击Jenkins的pkg包,一步一步点同意,默认8080端口2.使用命令行启动打开terminal,进入到war包所在目录,执行命令: java -jar ...
随机推荐
- ActionForward
一.只有登录才能显示的页面 这是一个很平常的问题,在访问某些网页的时候,只有登录才可以访问,以此保证安全. 实现原理也很简单,就是将一个属性设置在session中.在访问的时候进行判断即可. 例:re ...
- 解读JavaScript代码 var ie = !-[1,]
var ie = !-[1,]: 这句代码在IE9之前曾被称为世界上最短的IE判定代码.代码虽短但确包含了不少javascript基础知识在里面.在这个例子中代码执行时会先调用数组的toString( ...
- 【模拟】【HDU1443】 Joseph
Joseph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 用maven骨架生成项目速度慢的问题
最近从IntelliJ Idea 14的Community版本切换到Ultimate. 问题出现 最近从IntelliJ Idea 14的Community版本切换到Ultimate,key是从网络上 ...
- appium安装 For windows
java sdk,android SDK,maven,genymotion全部已经安装完毕,只是安装appium 因为现在的appium(AppiumForWindows_1_4_13_1)需要自己重 ...
- SQL语句函数详解__sql聚合函数
函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类:单行函数.组函数 本文将讨论如何使用单行函数及 ...
- 重写TextView,实现圆形背景,文本居中显示
最近,在做考试试题排版,产品提出题号希望显示成圆形背景,序号文本居中显示. (有点问题:文本没有绝对居中,暂时没做处理.) 为此,我采取的方式是重写TextView的onDraw方法,绘制一个圆形背景 ...
- UINavigationController 和 UITabBarController
UINavigationController当设置根控制器的时候,意思就是把根控制器压入栈内,当我们push的时候,我们把下一个控制器压入栈内,当我们pop的时候把上面的控制器的内存释放 UITa ...
- Intel 编译Boost库
C:\Windows\SysWOW64\cmd.exe /E:ON /V:ON /K ""C:\Program Files (x86)\Intel\Composer XE 2013 ...
- avalon前端js直接通过ajax请求传一个对象到后台
代码如下: //企业开票信息 vm.invoiceInfo = { companyId : "", //企 ...