文章目录
前言
本专栏将学习最新的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