**提示:本系列文章适合对Go有持续冲动的读者**
### 一、见初
国内官网[https://golang.google.cn/](https://golang.google.cn/)
##### 1.linux二进制安装
```shell
#获取go1.16.4
wget https://golang.google.cn/dl/go1.16.4.linux-amd64.tar.gz
tar -xf go1.16.4.linux-amd64.tar.gz -C /usr/local
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
source /etc/profile
#验证安装
[root@VM-0-5-centos bin]# go version
go version go1.16.4 linux/amd64
```
---
##### 2.Hello, Water Man!
vim `water_man.go`
```go
package main
import "fmt"
func main() {
fmt.Println("Hello, Water Man!")
}
```
go run `water_man.go`
```
Hello, Water Man!
```
go应用可直接编译目标平台二进制可执行文件
```shell
[root@VM-0-5-centos hellogo]# go build water_man.go
[root@VM-0-5-centos hellogo]# ls
water_man water_man.go
[root@VM-0-5-centos hellogo]# ./water_man
Hello, Water Man!
```
### 二、了解go
##### 1. go module
golang的包管理工具。
包设计的初衷是方便模块化设计和使用,在go中模块是包的集合,如果模块需要被其他人使用,则应该在`go mod init`初始化时以可以下载的web地址命名,产生的go.mod在go运行或编译时可跟踪依赖。
初始化`rush_b`模块
```shell
mkdir rush_b && cd rush_b
[root@VM-0-5-centos rush_b]# go mod init github.com/csgo/rush_b
go: creating new go.mod: module github.com/csgo/rush_b
#获得包含包列表名和go版本号的go.mod文件
[root@VM-0-5-centos rush_b]# ls
go.mod
```
创建`rush_b.go` 编写模块实现函数,**用于共享的功能模块函数首字母应大写**。
```go
package rush_b
import "fmt"
func Rush(name string) string{
message := fmt.Sprintf("%v, Follow me!",name)
return message
}
```
- go中函数定义中需要把声明的类型放在后面。
![img](https://markdown-1257692304.cos.ap-nanjing.myqcloud.com/markdown_img/function-syntax.png)
- `:=` 相当于同时定义和赋值,是下面的简写
```go
var message string
message = fmt.Sprinf("%v,Follow me!",name)
```
创建好`go.mod` 、`rush_b.go`后我们的`github.com/csgo/rush_b`模块就创建好了,接下来该考虑怎么引用它。
同理我们创建一个water_man文件夹
```shell
[root@VM-0-5-centos hellogo]# ll water_man/
total 8
-rw-r--r-- 1 root root 32 May 11 20:49 go.mod
-rw-r--r-- 1 root root 169 May 11 20:54 water_man.go
```
导入rush_b模块,使用其中的rush函数。
```
package main
import (
"fmt"
"github.com/csgo/rush_b"
)
func main() {
fmt.Println("Hello")
message :=rush_b.Rush("water man")
fmt.Println(message)
}
```
go run之后会根据地址去下载模块,由于模块是本地模块,所以我们`go mod edit --replace=github.com/csgo/rush_b=../rush_b` 告诉go 使用本地模块。
![image-20210511205856887](https://markdown-1257692304.cos.ap-nanjing.myqcloud.com/markdown_img/image-20210511205856887.png)
再此`go run`,正常调用了rush_b模块的Rush函数。
![image-20210512143910499](https://markdown-1257692304.cos.ap-nanjing.myqcloud.com/markdown_img/image-20210512143910499.png)
##### 2.errors与log 用于规范错误提示和日志排查。
当调用的Rush函数入参为空时返回错误。
```go
//rush_b.go
package rush_b
import (
"fmt"
"errors"
)
func Rush(name string) (string,error){
if name == ""{
return "",errors.New("empty name")
}
message := fmt.Sprintf("%v, Fllow me!",name)
return message,nil
}
//water_man.go
package main
import (
"fmt"
"log"
"github.com/csgo/rush_b"
)
func main() {
//fmt.Println("Hello")
log.SetPrefix("logging:") //设置前缀
log.SetFlags(0)
message,err := rush_b.Rush("")
fmt.Println(message)
if err !=nil{
//fmt.Println("it is an err")
log.Fatal(err) //打印error
}
}
[root@VM-0-5-centos water_man]# go run water_man.go
logging:empty name
exit status 1
```
##### 3.让S1mple跟我rush B
`rush_b.go` 当调用Rush时会随机返回addr切片中的一个标语。
```go
package rush_b
import (
"fmt"
"errors"
"math/rand"
"time"
)
func Rand_init(){ //随机数种子
rand.Seed(time.Now().UnixNano())
}
func RandomFormat() string {
addr :=[]string{
"%v ,follow me rush A",
"%v ,follow me rush B",
"%v ,follow me rush dust2",
}
return addr[rand.Intn(len(addr))] //len函数、Intn方法返回一个[0,n)的整数
}
func Rush(name string) (string,error){
if name == ""{
return "",errors.New("empty name")
}
message := fmt.Sprintf(RandomFormat(),name)
return message,nil
}
```
`water_man.go`
```go
package main
import (
"fmt"
"log"
"github.com/csgo/rush_b"
)
func main() {
//fmt.Println("Hello")
rush_b.Rand_init() //初始化种子
log.SetPrefix("logging:")
log.SetFlags(0)
message,err := rush_b.Rush("s1mple") //传入S1mple
fmt.Println(message)
if err !=nil{
//fmt.Println("it is an err")
log.Fatal(err)
}
}
```
`go run water_man.go` rush到哪不一定!
```shell
[root@VM-0-5-centos water_man]# go run water_man.go
s1mple ,follow me rush dust2
[root@VM-0-5-centos water_man]# go run water_man.go
s1mple ,follow me rush B
[root@VM-0-5-centos water_man]# go run water_man.go
s1mple ,follow me rush dust2
[root@VM-0-5-centos water_man]#
```
##### 4. 让top3给我打佯攻
使用到了map,类似于python中的字典
```go
// rush_b.go
package rush_b
import (
"fmt"
"errors"
"math/rand"
"time"
)
func Rand_init(){
rand.Seed(time.Now().UnixNano())
}
func RandomFormat( name string) (string,error) {
if name == ""{
return "",errors.New("empty name")
}
addr := []string {
"%v ,follow me rush A",
"%v ,follow me rush B",
"%v ,follow me rush dust2",
}
return fmt.Sprintf(addr[rand.Intn(len(addr))],name),nil
}
func Yg(names []string ) (map[string]string,error){ //佯攻
messages := make(map[string]string) // map初始化
for _,name := range names{
message,err := RandomFormat(name)
if err != nil {
return nil, err
}
messages[name] = message
}
return messages,nil
}
//water_man.go
package main
import (
"fmt"
"log"
"github.com/csgo/rush_b"
)
func main() {
//fmt.Println("Hello")
rush_b.Rand_init()
log.SetPrefix("logging:")
log.SetFlags(0)
hero:=[]string{"s2mple","zywoo1","device"}
message,err := rush_b.Yg(hero)
for i := 0; i < len(hero); i++ {
fmt.Println(message[hero[i]])
}
if err !=nil{
//fmt.Println("it is an err")
log.Fatal(err)
}
}
```
`go run water_man.go `执行情况如下:
```shell
[root@VM-0-5-centos water_man]# go run water_man.go
s2mple ,follow me rush B
zywoo1 ,follow me rush A
device ,follow me rush A
```
---
文章有不足的地方欢迎在评论区指出。
参考书籍:go语言圣经
欢迎收藏、点赞、提问。关注公众号-`容器云实践`,一起涨知识。
有疑问加站长微信联系(非本文作者)