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

介绍

本文会在一个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
$

版权申明:本文为博主原创文章,转载请保留原文链接及作者。

Go测试开发(一) 怎么写Go代码的更多相关文章

  1. NX二次开发-NX+VS写代码设断点调试技巧

    在做NX二次开发的时候写完代码,编译可以通过,但是执行的时候却没有反应,或者得到的结果不对,说明肯定有地方传值出错了.我在查找代码错误的时候有几种方法:1.uc1601打印函数输入和输出的值看对不对. ...

  2. 技术调研,IDEA 插件怎么开发「脚手架、低代码可视化编排、接口生成测试」?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 不踩些坑,根本不是成熟的码农! 你觉得肯德基全家桶是什么?一家人一起吃的桶吗,就那么 ...

  3. ESP8266开发之旅 进阶篇⑤ 代码规范 —— 像写文章一样优美

    1.前言     之前,一直在跟大伙分享怎么去玩蓝牙模块,怎么去玩wifi模块,怎么去玩json,然后有很多小伙伴就留言各种问题或者说直接怼他的代码过来让我看,然后我就一脸懵逼(代码中到处各种abcd ...

  4. 为企业应用开发提速,写给企业IT部门的低代码开发基础知识

    简介:应用程序开发长期以来一直是IT部门和业务部门面临的问题. IT部门总是被新的应用程序需求弄得不堪重负.他们不可能完成业务部门想要完成的每一个项目. 同时,业务部门的用户厌倦了等待,并开始完全绕过 ...

  5. 笔试测试开发题三道(python)

    笔试遇到的三道测试开发题,虽然都不难,但关键还是思路吧!我想在开发东西的时候应该具备的就是思路,有了思路尝试去写,或查相关文档或代码,在此基础上需要不断调整最终达到需求.思路又是在不断练习中获得的. ...

  6. Android NDK开发(五)--C代码回调Java代码【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41862479 在上篇博客里了解了Java层是怎样传递数据到C层代码,并且熟悉了大部 ...

  7. 什么是测试开发工程师-google的解释

    什么是测试开发工程师-google的解释 “ 软件测试开发工程师[SET or Software Engineer in Test],和软件开发工程师一样是开发工程师,主要负责软件的可测试性.他们参与 ...

  8. 翻译一篇文章:It's Difficult to Grow a Test Developer(成为测试开发工程师的艰辛)

    翻译一篇文章:It's Difficult to Grow a Test Developer(成为测试开发工程师的艰辛)   以下文章是送给来poptest学习测试开发工程师的学员们,很多人想测试工程 ...

  9. 测试开发Python培训:抓取新浪微博抓取数据-技术篇

    测试开发Python培训:抓取新浪微博抓取数据-技术篇   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的se ...

随机推荐

  1. 【NOIP2015四校联训Day7】 题 题解(Tarjan缩点+DFS)

    前言:没错,这题的名字就这么直白.我们考试题. ------------------ 你需要完成$n$道题目.有一些题目是相关的,当你做一道题的时候,如果你做过之前对它有帮助的题目,你会更容易地做出它 ...

  2. DataGrip 2020.1 安装与激活

    1 软件下载 百度网盘: 链接:https://pan.baidu.com/s/1kHSq1XS0i4YDF0HuzsxCLg 提取码:djyc 2 安装 解压文件后点击 datagrip-2020. ...

  3. 在Swoole上加速Laravel应用

    Swoole是用于PHP的生产级异步编程框架.它是用纯C语言编写的PHP扩展,它使PHP开发人员可以在PHP中编写高性能,可伸缩的并发TCP,UDP,Unix套接字,HTTP,WebSocket服务, ...

  4. 调用thrift出现No handlers could be found for logger "thrift.transport.TSocket"

    1.问题 使用thrift版本为0.10,在0.8没有这个问题 其中ncTAgent是代码中封装的thrift接口的结构,在thrift服务端没有启动的时候,应该拋错为连接不到.但是拋错的堆栈输出之前 ...

  5. Android Studio同时监听多个Button实现activity跳转

    MainActivity.java: package com.example.test; import android.content.Intent; import android.os.Bundle ...

  6. maven配置问题

    今天配置maven环境,最后总是显示 百度好多方法,都没解决,最后查看了一下maven目录下的mvn.cmd文件发现里面的jdk引用名用的是%JAVA_HOME%..... 看完就发现问题了,自己装了 ...

  7. 从系统报表页面导出20w条数据到本地只用了4秒,我是如何做到的

    背景 最近有个学弟找到我,跟我描述了以下场景: 他们公司内部管理系统上有很多报表,报表数据都有分页显示,浏览的时候速度还可以.但是每个报表在导出时间窗口稍微大一点的数据时,就异常缓慢,有时候多人一起导 ...

  8. 使用Prometheus监控Golang服务-基于YoyoGo框架

    Prometheus Prometheus是一个非常棒的工具,结合grafana能够让我在不写代码,或者少写代码的情况下搭建一套有效的监控体系.这里介绍一下Prometheus监控golang程序的方 ...

  9. Deep learning-based personality recognition from text posts of online social networks 阅读笔记

    文章目录 一.摘要 二.模型过程 1.文本预处理 1.1 文本切分 1.2 文本统一 2. 基于统计的特征提取 2.1 提取特殊的语言统计特征 2.2 提取基于字典的语言特征 3. 基于深度学习的文本 ...

  10. 0x01 基本算法-位运算 a^b

    #include<bits/stdc++.h>using namespace std;int power(int a, int b, int p){    int ans = 1%p;   ...