跳至主要内容

Go语言学习笔记|包


在程序语言里包就是独立的代码块或者功能块,有的包只实现特别简单的功能,比如字符串处理,有些包实现一个比较复杂的功能,比如无限极分类。很多语言都有包的概念,例如,php里用composer来管理包,方便开发者下载更新,Go语言里的包也是类似概念

以mac系统为例,打开/usr/local/go/src 这里就是Go内置的所有包


通过文件夹名可以看到包的命名规范

Go语言包的命名,遵循简洁、小写、和go文件所在目录同名的原则 这样做的优点是便于我们引用,书写以及快速定位查找

简洁、小写很好理解,那么什么是go文件所在目录同名呢?


如:在/usr/local/go/src 下有一个小写fmt的文件夹,进入fmt文件夹有诸多小写英文命名以.go为后缀的文件,这些文件就是包,打开任何一个文件,在第一行非注释代码里都声明了:package fmt,这里的fmt就是包名,包名与go文件所在目录fmt同名

声明包:

我们用关键字 package来声明包,如果你用IDE的话,当你打出package就会自动高亮


导入包:

Go用import关键字来导入,

只导入一个包 :

import "fmt"


导入多个包:

import (
    "net/http"
    "fmt"
)

问题一:net/http 很明显,我们要导入的是net下的http.go这个包,但是fmt呢?刚才打开fmt下有很多文件,具体导入哪个呢?

如果导入的时候你没有指定到具体的文件,那么Go默认导入这个包的所有文件。

问题二:程序怎么知道去哪个路径找到相应的包呢?

如果你有印象的话在安装Go的时候,要求你配置过两个环境变量,一个是GOROOT,另一个是GOPATH,这就是配置这两个环境变量的作用之一,我们一般会把GOROOT配置为Go的安装目录,GOPATH配置为我们的工程目录,Go编译器会优先在GOROOT里搜索包,如果没搜到会继续在GOPATH里搜索,一旦找到就停止搜索,如果都没找到,编译就不成功。

这里有个有趣的事情,我们导入了一个包,这个包也存在,但是程序里没有用到这个包里的任何方法,会怎么样呢?如果是php里include了一个代码里没有用的文件,一切是那么的正常,但是在Go里是不允许的,编译的时候会异常,关于这个做法,传言Go的团队也是多番讨论,最终还是决定不可以这样做,应该是与Go奉行的极简原则有关,“没有用的代码一行也不允许出现”,嗯,就是这么强势!但是有时候,我们要导入一个包,我们也确定我们不使用它(相信我,确实有这种情况,后面会讲到),怎么办呢?我们在包名前面加一个下划线就好了,这样就能“骗”过编译器了~

import (
    _ "flag"
    "fmt"
)


命名导入



作为程序员命名是一件令人头疼的事情,有时候想不出来什么样的名字,有时候想出来了觉得挺高大上结果发现已经有其他的包命名了,这样就会有命名重复的问题,当然你也可以换个名字(我这里不推荐),遇到包重名的时候,我们只需要在包名前加上另一个英文单词就行了,如果是为了区别与标准库,我习惯在命令里加上前缀"my"


package main

import (
    "fmt"
    myfmt "mylib/fmt"
)

func main() {
    fmt.Println()
    myfmt.Println()
}


特殊的包:main包



当把一个go文件的包名声明为main时,就等于告诉go编译程序,我这个是一个可执行的程序,那么go编译程序就会尝试把它编译为一个二进制的可执行文件,如果你在mac下的话,直接./文件名就可以看到执行效果,windows会生成一个.exe的可执行文件

一个main的包,一定会包含一个main()函数,php里没有这样的规范,C和Java都有main()函数,它是一个程序的入口,没这个函数,程序就无法执行。

评论