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 ...
随机推荐
- hdu 3061 (最大权闭合图)
分析:城池之间有依赖关系,汇点与能获得兵力的城池连接,容量为可以获得的兵力,损耗兵力的城池与汇点连接容量为损耗的兵力,有依赖关系的城池间连边,容量为无穷大,跑网络流求出的最小割就是损耗的最小兵力,,, ...
- Android Studio代码自己主动提示无效(not available in Power Save mode)
针对一位博友提的问题,我这边写出来,预计还是非常多人会碰到这个问题,可是不知道怎样解决的. 就是在设置了代码自己主动提示功能后,发现不生效的,怎样设置代码自己主动提示请戳这:Android Studi ...
- apache 三种工作模式的讲解
Apache 2.X 支持插入式并行处理模块,称为多路处理模块(MPM).在编译apache时必须选择也只能选择一个MPM,对类UNIX系统,有几个不同的MPM可供选择,它们会影响到apache的速 ...
- 动态根据checkbox 增加Dom
<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" ...
- android 获取屏幕尺寸
文章转载自:http://blog.csdn.net/congqingbin/article/details/7474276// 通过WindowManager获取 DisplayMetrics dm ...
- WPF中当鼠标移到按钮上时,按钮的背景图片消失的问题
如果给按钮设置了背景图片,当鼠标移到按钮上的时候,按钮就好变成一个浅蓝色的按钮,背景图片就消失了,对于这个问题有很多解决方法,我只分享一下我的解决方法. 我第一次用的方式是在按钮中添加一个图片,不用背 ...
- linux学习笔记之线程同步机制
一.基础知识. 1:线程同步机制:互斥量,读写锁,条件变量,自旋锁,屏障. 1,互斥量:每个进程访问被互斥量保护的资源时,都需要先对互斥量进行判断. 1)互斥量重要属性:进程共享属性,健壮属性,类型属 ...
- 【iOS】objective-c 文档生成工具 appledoc
最近做ios framework的一些测试,提供给其他开发者使用的framework,API文档变得更加重要,以前没有接触过,这次尝试使用了一把appledoc来生成一下文档,感觉还不错. 首先,是从 ...
- java 小数点取2位并且四舍五入
BigDecimal bd = new BigDecimal(0.0199999999999); System.out.println("res:"+bd.setScale(2, ...
- hdu 5823 color II 状压dp
题目链接 给n个点 n<=18. 然后给出它们两两之间是否有边相连. 问你这个图的所有子集,最少要用多少种颜色来染色, 如果两个点相连, 那么这两个点不能染同样的颜色. 先预处理出所有的点独立集 ...