zoukankan      html  css  js  c++  java
  • Go编程(一) 怎么写Go代码

    Go编程(一) 怎么写Go代码

    Go编程(二) 多线程简单斗地主

    持续更新中...


    安装过程略过,网上搜一大把。

    介绍

    本文会在一个module中开发一个简单的Go package。

    同时介绍go tool(也就是go命令行)。

    以及如何fetch,build和install Go的modules,packages,commands。

    代码组织

    Go是按packages来组织代码的。一个package == 一个目录。

    同一个package中的functions,types,variables,和constants是共享的。也就是包访问权限,java默认也是包访问权限。

    packages是放在module中的,module是通过go.mod文件来定义的。典型的,一个repository只有一个go.mod,放在根目录。

    可以使用go mod init name来创建这个文件。在go run后会生成go.sum文件,内容是go.mod的加密哈希。

    repository也允许有多个module,module的packages是go.mod所在的目录,如果子目录也有go.mod,那么这个子目录的packages就属于子目录module。

    第一个程序

    假设module path是example.com/user/hello

    $ mkdir hello # Alternatively, clone it if it already exists in version control.
    $ cd hello
    $ go mod init example.com/user/hello
    go: creating new go.mod: module example.com/user/hello
    $ cat go.mod
    module example.com/user/hello
    
    go 1.14
    $
    

    Go源文件的第一个语句必须是package name。程序入口必须是package main

    package main
    
    import "fmt"
    
    func main() {
    	fmt.Println("Hello, world.")
    }
    

    喜闻乐见Hello World。

    现在可以build和install,

    $ go install example.com/user/hello
    $
    

    这条命令会build然后生成可执行二进制文件(这是我比较喜欢Go的一个原因,直接生成可执行文件,省去了安装依赖的麻烦)。

    buildinstall命令都可以生成可执行文件。不同点在于

    • go build 不能生成包文件, go install 可以生成包文件
    • go build 生成可执行文件在当前目录下, go install 生成可执行文件在bin目录下

    install生成文件的bin目录是根据环境变量来的。按以下顺序检查

    • GOBIN
    • GOPATH

    如果都没有设置,就会生成到默认GOPATH(Linux $HOME/go 或Windows %USERPROFILE%\go)。

    示例的二进制文件会生成到$HOME/go/bin/hello(Windows的话就是%USERPROFILE%\go\bin\hello.exe)。

    可以查看环境变量GOBIN和GOPATH的值

    go env
    

    也可以设置GOBIN

    $ go env -w GOBIN=/somewhere/else/bin
    $
    

    设置后可以重置

    $ go env -u GOBIN
    $
    

    GOPATH需要到系统环境变量进行修改。

    install等命令需要在源文件目录下执行,准确点说是“当前工作目录”。否则会报错。

    在当前目录执行,以下等价

    $ go install example.com/user/hello
    
    $ go install .
    
    $ go install
    

    验证下结果,为了方便,添加install目录到PATH

    # Windows users should consult https://github.com/golang/go/wiki/SettingGOPATH
    # for setting %PATH%.
    $ export PATH=$PATH:$(dirname $(go list -f '{{.Target}}' .))
    $ hello
    Hello, world.
    $
    

    如果cd到了install的bin目录,也可以直接

    $ hello
    Hello, world.
    $
    

    现阶段Go的很多库都是放在GitHub等代码托管网站上面的,使用Git进行提交

    $ git init
    Initialized empty Git repository in /home/user/hello/.git/
    $ git add go.mod hello.go
    $ git commit -m "initial commit"
    [master (root-commit) 0b4507d] initial commit
     1 file changed, 7 insertion(+)
     create mode 100644 go.mod hello.go
    $
    

    Go命令通过请求相应的HTTPS URL,并读取嵌入在HTML响应中的元数据<meta>标签,来定位包含给定module path的repository

    Bitbucket (Git, Mercurial)
    
    	import "bitbucket.org/user/project"
    	import "bitbucket.org/user/project/sub/directory"
    
    GitHub (Git)
    
    	import "github.com/user/project"
    	import "github.com/user/project/sub/directory"
    
    Launchpad (Bazaar)
    
    	import "launchpad.net/project"
    	import "launchpad.net/project/series"
    	import "launchpad.net/project/series/sub/directory"
    
    	import "launchpad.net/~user/project/branch"
    	import "launchpad.net/~user/project/branch/sub/directory"
    
    IBM DevOps Services (Git)
    
    	import "hub.jazz.net/git/user/project"
    	import "hub.jazz.net/git/user/project/sub/directory"
    

    很多托管网站已经为Go的repository提供了元数据,为了共享module,最简单的办法就是让module path匹配repository的URL。

    从module import packages

    先在名字为morestrings的package中创建一个reverse.go文件,实现字符串反转

    // Package morestrings implements additional functions to manipulate UTF-8
    // encoded strings, beyond what is provided in the standard "strings" package.
    package morestrings
    
    // ReverseRunes returns its argument string reversed rune-wise left to right.
    func ReverseRunes(s string) string {
    	r := []rune(s)
    	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
    		r[i], r[j] = r[j], r[i]
    	}
    	return string(r)
    }
    

    由于ReverseRunes函数是大写的,所以是公有的,可以被其他packages import。

    先build测试下编译成功

    $ cd $HOME/hello/morestrings
    $ go build
    $
    

    因为只是在package中,不是在module根目录,go build不会生成文件,而是会把compile后的package保存到local build cache中。

    接着在hello.go中import

    package main
    
    import (
    	"fmt"
    
    	"example.com/user/hello/morestrings"
    )
    
    func main() {
    	fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
    }
    

    然后install hello

    $ go install example.com/user/hello
    

    验证,import成功,字符串反转

    $ hello
    Hello, Go!
    

    从远程remore modules import packages

    可以用import path通过版本控制系统来获取package源码,如Git或Mercurial。

    示例,使用github.com/google/go-cmp/cmp

    package main
    
    import (
    	"fmt"
    
    	"example.com/user/hello/morestrings"
    	"github.com/google/go-cmp/cmp"
    )
    
    func main() {
    	fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
    	fmt.Println(cmp.Diff("Hello World", "Hello Go"))
    }
    

    当运行命令go install go build go run的时候,go命令会自动下载远程module,然后写到go.mod文件中

    $ go install example.com/user/hello
    go: finding module for package github.com/google/go-cmp/cmp
    go: downloading github.com/google/go-cmp v0.4.0
    go: found github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.4.0
    $ hello
    Hello, Go!
      string(
    - 	"Hello World",
    + 	"Hello Go",
      )
    $ cat go.mod
    module example.com/user/hello
    
    go 1.14
    
    require github.com/google/go-cmp v0.4.0
    $
    

    国内容易超时,可以使用代理走国内镜像

    七牛云

    go env -w GO111MODULE=on
    go env -w GOPROXY=https://goproxy.cn,direct
    

    阿里云

    go env -w GO111MODULE=on
    go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
    

    module依赖会自动下载到GOPATH指定目录的pkg/mod子目录。

    module指定版本的下载内容,是在所有其他require这个版本的modules中共享的,所以go命令会标记这些文件和目录为只读的。

    可以使用命令删除所有下载的modules

    $ go clean -modcache
    $
    

    测试

    Go有个轻量的测试框架,go testtesting package

    测试框架识别以_test.go结尾的文件,包含TestXXX命名的函数,函数签名func (t *testing.T)。如果函数调用失败如t.Errort.Fail,那么test就会失败。

    示例,新建$HOME/hello/morestrings/reverse_test.go文件,添加morestrings package的测试代码

    package morestrings
    
    import "testing"
    
    func TestReverseRunes(t *testing.T) {
    	cases := []struct {
    		in, want string
    	}{
    		{"Hello, world", "dlrow ,olleH"},
    		{"Hello, 世界", "界世 ,olleH"},
    		{"", ""},
    	}
    	for _, c := range cases {
    		got := ReverseRunes(c.in)
    		if got != c.want {
    			t.Errorf("ReverseRunes(%q) == %q, want %q", c.in, got, c.want)
    		}
    	}
    }
    

    运行测试

    $ go test
    PASS
    ok  	example.com/user/morestrings 0.165s
    $
    

    所有文章公众号【测试开发刚哥】首发!

    版权申明:本文为博主原创文章,转载请保留原文链接及作者。
  • 相关阅读:
    ie用document.getElementsByName获取不到
    js_设置光标到文本的最后位置
    js-转大小写
    mysql查询数据表的路径
    myeclipse导出javadoc时特殊字符 尖括号
    keyCode码集合
    mysql查询数据库约束
    oracle查询每个表的占用空间
    MYSQL复制表
    MacOs上的Intellij idea高频快捷键总结(2018.1版本)
  • 原文地址:https://www.cnblogs.com/df888/p/13616952.html
Copyright © 2011-2022 走看看