前些天带爸妈去上海、杭州玩了一下, 感觉很久没写博客了。
“协程”在手, 说go就go.
以后尽量少扯C++, 多说go, 本文来说说go中的一些基本概念,如包,import, GOROOT, GOPATH, src, pkg, bin等, 主要是理解清楚这些基本的东东。
来看看, 工作目录是:/home/ubuntu/taoge/go/proj, 在该目录下,创建一个src/main目录,其中有main.go文件:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ pwd
/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ cd src/main/
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ ls
main.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
main.go内容:
package main
import (
"calc/add"
"calc/subtract"
"fmt"
)
func main() {
fmt.Println(add.Add(1, 2))
fmt.Println(subtract.Subtract(1, 2))
}
编译运行一下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ go run main.go
main.go:4:2: cannot find package "calc/add" in any of:
/usr/lib/go-1.6/src/calc/add (from $GOROOT)
/home/ubuntu/go/src/calc/add (from $GOPATH)
main.go:5:2: cannot find package "calc/subtract" in any of:
/usr/lib/go-1.6/src/calc/subtract (from $GOROOT)
/home/ubuntu/go/src/calc/subtract (from $GOPATH)
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
提示在GOROOT和GOPATH对应的目录下没法找到calc/add和calc/subtract包。必然的! 因为我们根本就没有实现这两个包, 所以, 还是老老实实的来写calc/add和calc/subtract包吧:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src$ ls
calc main
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src$ ls calc/add/
add.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src$ ls calc/subtract/
subtract.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src$
add.go代码:
package add
func Add(x, y int) int {
return x + y
}
subtract.go代码:
package subtract
func Subtract(x, y int) int {
return x - y
}
好了, 再次来编译并执行一下main.go:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ go run main.go
main.go:4:2: cannot find package "calc/add" in any of:
/usr/lib/go-1.6/src/calc/add (from $GOROOT)
/home/ubuntu/go/src/calc/add (from $GOPATH)
main.go:5:2: cannot find package "calc/subtract" in any of:
/usr/lib/go-1.6/src/calc/subtract (from $GOROOT)
/home/ubuntu/go/src/calc/subtract (from $GOPATH)
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
还是不行, 为什么呢? 因为去找的路径是GOROOT和GOPATH, 而我们写的add和subtract并不在这两个目录下, 怎么办?直接把add.go和subtract.go对应的路径加到GOPATH中去即可(因为GOROOT是go的安装路径, 所以不建议修改GOROOT, 而是修改与工程目录有关的GOPATH), 如下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ echo $GOPATH
/home/ubuntu/go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ GOPATH=$GOPATH:/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ echo $GOPATH
/home/ubuntu/go:/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ go run main.go
3
-1
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
编译运行一下,终于OK.
几个点需要注意(仅以add为例,subtract同理):
1. add.go中的Add函数名首字母必须大写, 比如Add, Addxxx.
2. add.go的改名为addyyy.go也可以,查找add包的时候,并不会根据add.go这个文件名来查找。
3. 把calc/add目录改为calc/addzzz则不行, 因为在main.go中,import的是calc/add路径, 当然, 如果同步改掉main.go中的import内容为calc/addzzz, 也是可以的。 特别注意:此时add.go中package的add声明和main.go中的add包调用不一定要改为addzzz, 所以, 严格地说,import的是包所在的路径, 而不是包名。完全可以import calc/addzzz, 而包名依然为add. 但是,强烈建议这四处统一一致。
4. main中调用add.Add(1,2)时,add是包, 必须跟add.go中的package处的add包名一致,否则错误。
5. import后, 怎么去查找对应的包呢? 思考一下, 很简单,无非就是GOROOT和GOPATH. 也应该明白了, src这个目录名可不是能随便取的。
其实, 这些都是非常基础的, 也很好理解。
借这个例子, 我们来说说go的src,pkg, bin, 当前的目录结构如下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ tree
src
calc
add
add.go
subtract
subtract.go
main
main.go
5 directories, 3 files
在main目录下执行go run main.go的时候, 并不会产生新的文件, 而执行go build main.go的时候, 会产生新的可执行文件main, 如下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ go run main.go
3
-1
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ ls
main.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ go build main.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ ls
main main.go
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$ ./main
3
-1
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj/src/main$
好的, 我们把上述可执行文件main删除, 当前工程中的目录如下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ tree
src
calc
add
add.go
subtract
subtract.go
main
main.go
5 directories, 3 files
因为GOPATH已经包括了我们的工作目录:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ echo $GOPATH
/home/ubuntu/go:/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$
所以可以在任何目录下执行go install xxx命令, 来看下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ cd
ubuntu@VM-0-15-ubuntu:~$ pwd
/home/ubuntu
ubuntu@VM-0-15-ubuntu:~$ go install calc/add
ubuntu@VM-0-15-ubuntu:~$ go install calc/subtract
ubuntu@VM-0-15-ubuntu:~$
来看看目录有什么变化:
ubuntu@VM-0-15-ubuntu:~$ cd -
/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ tree
pkg
linux_amd64
calc
add.a
subtract.a
src
calc
add
add.go
subtract
subtract.go
main
main.go
8 directories, 5 files
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$
可以看到, 多了pkg目录, 里面有什么呢? 一看便知, 其中.a文件是不是很像之前在C++中经常用到的静态库?
我们继续在任何目录下来install, 如下:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ cd -
/home/ubuntu
ubuntu@VM-0-15-ubuntu:~$ go install main
结果有什么变化呢?来看看:
ubuntu@VM-0-15-ubuntu:~$ cd -
/home/ubuntu/taoge/go/proj
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ tree
bin
main
pkg
linux_amd64
calc
add.a
subtract.a
src
calc
add
add.go
subtract
subtract.go
main
main.go
9 directories, 6 files
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ ./bin/main
3
-1
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$
对了bin目录,其中有可执行文件main, 无需多说。
最后思考一个问题, 删除pkg和bin目录, 直接执行go install main (不执行go install calc/add和go install calc/subtract), 会怎样呢? 结果仍是:
ubuntu@VM-0-15-ubuntu:~/taoge/go/proj$ tree
bin
main
pkg
linux_amd64
calc
add.a
subtract.a
src
calc
add
add.go
subtract
subtract.go
main
main.go
9 directories, 6 files
不多说。