Golang之路 环境搭建及包的使用、测试和管理 (1)

导读:本篇文章讲解 Golang之路 环境搭建及包的使用、测试和管理 (1),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com


前言

本专栏将学习最新的golang技术,以及gin框架,也会出现例题等(当看到例题的时候不妨自己先动手尝试)。

本章需要一点github的知识,如有出错或有待优化的代码可在评论指出(本系列所有操作将在windows10中进行) 。

一、Golang的起源

Go是一种快速、静态类型的编译语言,感觉就像是一种动态类型的解释语言。

其优点在于:

  • Go 具有表现力、简洁、干净和高效
  • 并发机制使编写充分利用多核和联网机器的程序变得容易
  • 新颖的类型系统支持灵活和模块化的程序构建(1.8后新增了泛型
  • 快速编译为机器码
  • 垃圾收集的便利性和运行时反射的强大功能

golang的强大背景(创造golang的开发人员都是计算机界的大神存在以及谷歌的维护)让其在云计算,虚拟化、以及区块链、后端服务器等有着优秀的表现。

二、Golang环境搭建、配置

Go代码必须放在工作空间内。它其实就是一个目录,其中包含三个子目录

  • src 目录包含Go的源文件,它们被组织成包(每个目录都对应一个包)
  • pkg 目录包含包对象
  • bin 目录包含可执行命令

目录结构如下(本次示例以D:\all_project\GolandProjects为工作环境变量根目录):

D:\all_project\GolandProjects
	- src
		-github.com
			- user	 
	- pkg
	- bin

这几个目录需要自己手动创建

为了方便以后自己定义包,我们可以在src下再新建一个github.com/user(这里所有的user换成你的github账号的名字)文件夹,至于怎么使用我们下面会讲到。

设置环境变量
在这里插入图片描述

bin目录如图:

在这里插入图片描述

三、如何下载包以及自定义、运行包

1.运行你的第一个go项目

这里我们可以养成一种习惯再以github.com/user/目录下创建go项目,方便我们后续上传,以及阅读。

创建hello/hello.go代码如下:

package main

import (
	"fmt"
)
func main() {
	fmt.Printf("Hello,World")
}

这里package main相当于主入口,所有的代码将经过main函数

我们在这里导入了一个fmt文件(其中包含格式化文本的功能,包括打印到控制台),这个包是我们在安装 Go 时获得的标准库包之一

对于如何将我们编写的包导入或者是从外部命令下载的包,我们下面再说。

go的项目运行方法有3种,分别为:

  • go run . (常用方式,编译执行)
  • go install (将项目打包成exe格式在bin目录下)
  • go build -o 包名 (将项目打包成exe格式在当前目录下)

记住一点,要在当前项目的根下执行,各个命令的具体使用场景我等会将配合例题讲解

不过在此之前,在go新版本的到来引入了mod,该文件的作用是相当于配置文件,创建方法如下:

go mod init github.com/user/hello // 命名规范,方便上传到github中供人下载

此时会在当前目录生成一个go.mod文件,内容如下:

module github.com/user/hello

go 1.18
)

初始化默认是这样的,后续我们会根据需求进行添加

通过go run . 执行控制台打印如下:

Hello,World

2.调用外部包中的代码

前面我们通过导入标准库包fmt在控制台打印了结果,那么我们该如何自己编写或下载其他的人的包呢?先讲如何下载他人的包并导入

我们将修改hello.go代码如下:

package main

import "fmt"

import "rsc.io/quote"

func main() {
    fmt.Println(quote.Go())
}

此时我们可以通过两种命令去下载模块

  • go get 包名(.代表下载所有依赖)
  • go mod tidy(等于 go get . 不过这是在当前目录下载依赖)

此时我们执行go mod tidy时有可能下载不了,我们需要通过设置代理才可以下载

// 通过 go env 可以查看我们的go配置信息
go env -w GOPROXY=https://goproxy.cn

下载成功后,我们不着急运行,先看看我们的go.mod文件如下:

module github.com/user/hello

go 1.18

require (
	rsc.io/quote v1.5.2
)

require (
	golang.org/x/text v0.3.6 // indirect
	rsc.io/sampler v1.3.0 // indirect
)

可以看到go默认的帮我们导入到了mod文件中(添加quote模块作为要求,以及用于验证模块的 go.sum 文件),并附带了版本号(默认情况下是最新的版本)。

可选: 了解更多mod知识

此时我们通过 go build 生成可执行文件在当前目录下执行:

.\hello.exe

控制台打印:

Don't communicate by sharing memory, share memory by communicating.

下面我们来介绍一下怎么自己编写包,并调用

在github.com/user目录下创建一个stringutil/revere.go如下:

package stringutil

// Reverse 将其实参字符串以符文为单位左右反转。
func Reverse(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)
}

这里有一个小细节我要讲,对于我们现在生成的函数Reverse时,这个函数开头要大写,这是go的规范(公用的),如果你使用小写命名函数,那么这个函数将只能在当前文件中使用(私有的) 。

函数里的代码是如何实现字符串翻转的现在不用管,我们创建mod文件

go mod init github.com/user/stringutil

好的,此时我们按照规范写好了,现在我们该修改hello.go文件如下:

package main

import (
	"fmt"
	"github.com/user/stringutil"
	"rsc.io/quote"
)

func main() {
	fmt.Println(quote.Go())
	fmt.Printf(stringutil.Reverse("!risoaiM ,olleH"))
}

此时我们回到hello根目录通过go mod tidy 下载是肯定不行的,因为我们并没有将stringutil文件夹上传到github上,所以我们需要配置一下go.mod文件如下:

module github.com/user/hello
// 这里是重定向
replace github.com/user/stringutil => ../stringutil

go 1.18

require (
	github.com/user/stringutil v1.0.0
	rsc.io/quote v1.5.2
)

require (
	golang.org/x/text v0.3.6 // indirect
	rsc.io/sampler v1.3.0 // indirect
)

这个操作相当于我们将路径重定向到了我们编写该路径的文件夹下

那么此时再通过go mod tidy 运行变会不再出现问题

也可以通过控制台命令生成如下:

go mod edit -replace github.com/user/stringutil=../stringutil

go mod tidy

此时效果和上面手动配置的一样,不过版本会变成随机的(因为这是我们没有上传到github上自己在文件夹中调用的,所以不存在版本,需自己修改版本后再上传到github上)。

通过go run . 运行 控制台打印如下:

Don't communicate by sharing memory, share memory by communicating.
Hello, Miaosir!

3.上传你的go项目并下载下来

现在我们该如何的发布我们的包,供其他人下载调用呢?本次示例我们将上传stringutil文件夹下的内容到github上。

创建好仓库后,控制台输入:

git init
git add .
git commit -m "first commit"
git remote add origin git@github.com:user/stringutil.git
git tag -a v1.0.0 -m "第一次写版本"
git push -u origin --tags
git push -u origin master

上传完毕后就可以让使用者通过地址下载下来自己使用了

测试一下,将hello文件夹下go.mod修改如下:

module github.com/user/hello

go 1.18

require (
	rsc.io/quote v1.5.2
)

require (
	golang.org/x/text v0.3.6 // indirect
	rsc.io/sampler v1.3.0 // indirect
)

hello.go如下:

package main

import (
	"fmt"
	"github.com/user/stringutil"
	"rsc.io/quote"
)

func reverse() string {
	return stringutil.Reverse("!risoaiM ,olleH")
}

func main() {
	fmt.Println(quote.Go())
	fmt.Printf(reverse())
}

运行 go mod tidy 进行下载,通过 go list -f ‘{{.Target}}’ 可以查看文件目录

通过 go install 将hello.exe打包到bin目录,因为我们写了环境变量,所以可以直接调用,通过控制台输入:

hello

控制台打印:

Don't communicate by sharing memory, share memory by communicating.
Hello, Miaosir!

四、如何进行代码测试?

虽然我们现在写的项目代码量不多,出现问题也能调试出来,不过往往在真正开发环境中,你写的很多的函数,这时候你需要通过测试来查看函数返回的结果是否为你预期的结果,不然真正的上线项目后会带来许多的问题。

我们这里就通过我们之前上传到github上的字符串翻转函数改进并进行测试,然后再重新上传成一个新版本。

stringutil.go代码如下:

package stringutil

import "errors"

// 将字符串翻转
func Reverse(s string) (string, error) {
	if s == "" {
		return s, errors.New("请输入字符串")
	}
	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), nil
}

这里的改进是判断字符串是否为空的情况下,是否能按照预期返回对应结果,并且多加了一个异常(不为空则error为nil)。

对于go的规范而言,以 _test.go 结尾的文件名告诉go test命令该文件包含测试函数(提供了内置的标准包testing)

创建stringutil_test.go如下:

package stringutil

import (
	"testing"
)

// 测试函数翻转功能是否有效
func TestReverse(t *testing.T) {
	name := "Test"
	msg, err := Reverse("tseT")
	if err != nil || name != msg {
		t.Fatalf(`Reverse("") = %q, %v, want "", error`, msg, err)
	}
}

// 测试我们的代码是否正确通过字符串为空得到报错结果
func TestReverseEmpty(t *testing.T) {
	msg, err := Reverse("")
	if msg != "" || err == nil {
		t.Fatalf(`Reverse("") = %q, %v, want "", error`, msg, err)
	}
}

此时控制台输入

go test -v

打印结果:

=== RUN   TestReverse
--- PASS: TestReverse (0.00s)
=== RUN   TestReverseEmpty
--- PASS: TestReverseEmpty (0.00s)
PASS
ok      github.com/user/stringutil     0.040s

然后将git代码进行更新

git add .
git commit -m "测试完成"
git tag -a v1.0.1 -m "测试版本生成"
git push origin master
git push origin --tags

本次使用的例子:https://github.com/miaojiaxi2004/stringutil/

练习:如何将gin写的项目打包成可执行文件?

Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 httprouter,速度提高了 40 倍 。

示例地址:https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01

要求:根据其要求使用该包,并删除assets.go尝试自己通过其提供的其他包生成一个assets.go。

结果:执行./assets-in-binary.exe后服务器直接运行

按照上面的链接给出的文档,先执行

go get github.com/gin-gonic/gin
go get github.com/jessevdk/go-assets-builder

然后

go-assets-builder html -o assets.go

这里直接这样写肯定是不行的,要用到我们前面说的go install 生成全局的exe文件,然后才可以调用该方法,那么我们该从哪里入手呢?

我们下载其他人的包的时候默认会在pkg下,然后从那个网站下载下来的后缀名+它的包名

这里的话总路径就是 pkg/mod/github.com/jessevdk下,那么我们直接去查看,发现这里是没有go.mod文件的。

那么这时候我们要自己手动创建go.mod文件进行编写,然后生成全局的exe文件,在进行打包操作。

不过再次之前我们需要在它的目录中找到main函数入口,查看它导入了什么,这里是builder.go如下:

package main

import (
	"github.com/jessevdk/go-assets"
	"github.com/jessevdk/go-flags"
	"os"
)

func main() {
	// 不用管
}

可以看到导入了go-assets和go-flags这两个是它自己的包,而os是标准库包,不需要导入

所以go.mod如下:

module github.com/jessevdk/go-assets-builder

require (
	github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15
	github.com/jessevdk/go-flags v1.5.0
)

go 1.18

好了,现在配置完成后就可以在go-assets-builder目录下进行编译打包了执行 go install,此时在我们全局的bin目录下就出现了打包成功的go-assets-builder.exe文件了。

那么我们回到之前被我们删除assets.go文件的example01目录,按照上面链接文档提示执行

go-assets-builder html -o assets.go

此时就没问题了,执行完成后就会生成新的assets.go文件了

然后继续往下执行

go build -o assets-in-binary.exe

这个命令是打包exe文件到当前文件夹目录,并取名为assets-in-binary

成功后执行 ./assets-in-binary.exe 控制台将会开启服务器如下:

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /                         --> main.main.func1 (1 handlers)
[GIN-debug] GET    /bar                      --> main.main.func2 (1 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.

此时浏览器访问http://localhost:8080/即可访问看到Hello,World

下载下来的模块中还有一个example02目录(这里的是已经写好的,通过 go build -o assets-in-binary2.exe 即可生成exe文件)

使用的打包方法是在go1.16之后提供了embed这个标准库包,然后按照其规范导入图片和模板。

有兴趣的朋友可以把这个当最后的练习看看:https://pkg.go.dev/embed@master

此时运行 ./assets-in-binary2.exe

浏览器访问:http://localhost:8080/public/assets/images/example.png

在这里插入图片描述

你会看到一只会魔法的土拨鼠…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/66839.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!