如何编写Go 代码 {How to Write Go Code}

来源:互联网 发布:js 初始化二维array 编辑:程序博客网 时间:2024/04/27 15:05

如何编写Go程序:


Code 结构

 GoPath 和  workspaces

   设计GO的一个目标就是写程序更加的容易,go的命令行不使用makefiles或者其他的配置文件来构建程序,取而代之的是使用源代码去发现互相的依赖或项目构建的条件,这意味着你的源代码和脚本总是同步的,始终保持一致。

  你必须要设置GoPath的环境变量,GOPATH 告诉程序或者其他一些GO的工具,Go的安装程序在系统中的哪个位置。GOPATH 是一系列程序的的路径,它展示系统的环境变量的路径,一个Unix系统的路径设置如下:

GOPATH=/home/user/ext:/home/user/mygo      在windows中是使用;(分号)作为分隔符;

 在列表中的每一个路径指定了特定的不同程序的工作环境,Go的工作环境包含了源文件和相关包和可执行command,它规定了三个目录的结构

1.src包含了Go的源文件;

2.pkg包含了编译后包的文件;

3.bin包含了可执行的程序;

 src的子目录包含独立的包,和其他的一些源文件(.go,.c,.h和.s),在每一个子目录中是子目录中的包。当构建一个程序导入"widget"包,go程序$GO ROOT中搜索/src/pkg/widget,如果包的源代码不在/src/pkg/widgt下。Go就用/src/widget,多个工作环境能提供更多的便利性和灵活性,但是现在我们只关心一个工作环境
 让我们通过一个简单的例子,
 首先,在src下面创建一个子目录$HOME/mygo
linux command mkdir -p $HOME/mygo/src #创建一个目录放置源代码 把下载的go包解压放入其中
其次,设置它为GOPATH路径,同时你也要指定bin目录到path的环境变量中,这样你就能够执行commands而不要指定完整的commands命令,
 在linux环境下的$HOME/.profile文件中导出变量为全局变量
 export GOPAHT=$HOME/mygo export PATH=$PAHT:$HOME/mygo/bin
Import paths
独立的包使用简短的路径,例如‘fmt’和‘net/http’用来方便的导入包,在你自己的项目中,导入自己编写代码的类路径很重要的一点是不要和将来可能增加的库和一些扩展库冲突
最好的方式是导入的包路径使用你自己本地的版本库的名称。一个例子,如果你的版本是在example.com 或者 code.google.com/p/example,你应该一开始就指定的包路径为“exaple.com/foo/bar” 或者 “code.google.com/p/example/foo/bar”,在导入独立的路径后go commands能够自动检验和编译导入的包,使用起来更加方便。
如果你不打算通过这个方式安装你的编写的程序,你至少应该使用唯一的前缀入“widgets/”,类路径为“widget/foo/bar”,一个很好的规则是使用你公司的项目名称做为前缀,如果公司名称不被其他组织使用的话,我们来做个例子  example/ 做为你的基本导入包路径
linux command $mkdir -p $HOME/src/example
Package names
 在Go源代码文件中的第一句必须是
 package name
 name是导入包的默认名称
 Go导入包的规则是name与导入该包路径的最后位置上的名称一致,例如导入“crypto/rot13”包,rot13必须作为包的名称name,没有要求在所有的包中包名要唯一,只要做到导入的路径是唯一的就可以了
 在example文件下建立一个名为newmath的包,
 linux command cd$GOPATH/src/example mkdir newmath
 建立一个文件名为$GOPATH/src/example/newmath/sqrt.go 文件包含下面的代码
 // Package newmath is a trivial example package.package newmath// Sqrt returns an approximation to the square root of x.func Sqrt(x float64) float64 {        // This is a terrible implementation.        // Real code should import "math" and use math.Sqrt.        z := 0.0        for i := 0; i < 1000; i++ {                z -= (z*z - x) / (2 * x)        }        return z}
要导入这个类,只要使用 import "example/newmath"

通过 Effective Go 学习关于Go更多的命名规范


Building and installing
Go command 包含了一系列的子commands。最核心的就是install,运行go install {importpath}编译和安装一个包及其依赖,install a package 意味着把包中的对象和可执行程序写入到pkg和工作环境的子目录中

Building a package

编译和安装newmath包,
go install example/newmath
如果这个包和依赖是这正确的,这个命令将不会有输出
如果install命令没有指定目录的路径,则install会默认使用当前路径,下面是一个和上面例子同样效果的命令
cd $GOPAHT/src/example/newmathgo install
命令正确执行后,当前工作区的目录树如下所示(假定我们运行在一个64位的linux操作系统上)
pkg/    linux_amd64/        example/            newmath.a  # package objectsrc/    example/        newmath/            sqrt.go    # package source
Building a command
go Command 认为包package main的代码为可执行的命令,并且安装二进制包到GOPATH‘s的子目录中
加入一个命令为名为hello到源代码树中,首先创建一个example/hello的目录
cd $GOPATH/src/examplemkdir hello
然后再创建一个文件$GOPATH/src/example/hello/hello.go,包含下面的Go code

// Hello is a trivial example of a main package.
package main

import (
        "example/newmath"
        "fmt"
)

func main() {
        fmt.Printf("Hello, world.  Sqrt(2) = %v\n", newmath.Sqrt(2))
}

接下来,运行go install,编译和安装这个command到$GOPATH/bin
go install example/hello
运行这个程序,使用它的名称hello
$GOPATH/bin/hello
Hello, world.  Sqrt(2) = 1.414213562373095
如果你加入了$HOME/mygo/bin到你的路径中,那么你可以忽略执行程序的路径
直接运行hello
Hello, world.  Sqrt(2) = 1.414213562373095
现在工作区的目录树如下显示

bin/
    hello              # command executable
pkg/
    linux_amd64/
        example/
            newmath.a  # package object
src/
    example/
        hello/
            hello.go   # command source
        newmath/
            sqrt.go    # package source
go command 还提供了build命令,编译所有的对象到临时文件中,而不安装到pkg目录或者bin目录下,当你编译和执行一个程序的时候,用导入路径的最后一个名称,做为编译后的文件名,写入到当前的目录中,go build 其实就是用来测试包和依赖的正确性,看能否被编译
Testing
Go 提供一个轻量级的测试框架 go test 用来测试包
你编写了一个测试文件以_test.go结尾,文件中包含方法名称为TestXXX func(t *testing.T),测试框架会运行每一测试方法,如果方法调用了failure function 如t.Error 或者t。Fail,这次测试的结果就失败了
测试newmath package 通过建立一个文件$GOPATH/src/example/newmath/sqrt_test.go,文件中包含下面代码

package newmath

import "testing"

func TestSqrt(t *testing.T) {
    const in, out = 4, 2
    if x := Sqrt(in); x != out {
        t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
        }
}
现在用go test 运行这个测试
go test example/newmath
ok    example/newmath 0.165s
运行 run go help 或者看testing package documentation 得到更多关于test的细节
Remote packages
一个导入包的方式是得到包中的源代码通过git 或者Mercurial.  go command 使用这个属性通过版本库自动得到包,例如,一写代码的Mercurial版本hosted在google Code
,code.google.com/p/go.example 如果你把版本的url加入到package的import 路径中,go get 将会得到代码,自动编译和安装
go get code。google。com/p/go.example/hello
$GOPAHT/bin/hello
Hello, world.  Sqrt(2) = 1.414213562373095
如果指定的包路径在工作目录中不存在,go get 将会把编译的对象放入到$GOPATH中,如果包已经存在了,go get将会忽略远程的版本文件
在运行了上面的go command后,当前的工作环境树如下所示
bin/
    hello                 # command executable
pkg/
    linux_amd64/
        code.google.com/p/go.example/
            newmath.a     # package object
        example/
            newmath.a     # package object
src/
    code.google.com/p/go.example/
        hello/
            hello.go      # command source
        newmath/
            sqrt.go       # package source
            sqrt_test.go  # test source
    example/
        hello/
            hello.go      # command source
        newmath/
            sqrt.go       # package source
            sqrt_test.go  # test source
hello command hosted在Google code上,和newmath(code.google.com/p/go.example/)保持相同的版本,导入相同的包路径的里一个规则
import “code。google。com/p/go.example/newmath”
这个规则提供一个更方便的方式使得go 包被其他人所使用,Go Project Dashboard 提供了系列的Go project 包含一些程序和库
了解更多的remote repository 使用go help remote



原创粉丝点击