golang笔记


关于golang.org无法连接

虽然推荐使用

1go get -u golang.org/x/sync

但很不幸,国内无法连接golang.org,所以只能曲线救国,借助github.com来安装相关的package

1git clone https://github.com/golang/sync ./
2# 或者
3git clone https://github.com/golang/sync
4mv sync $GOPATH/src/golang/x/

初始化Gopkg

1# go mod init jlb
2go: copying requirements from Gopkg.lock
3go: converting Gopkg.lock: stat google.golang.org/genproto@a8101f21cf983e773d0c1133ebc5424792003214: unrecognized import path "google.golang.org/genproto": https fetch: Get "https://google.golang.org/genproto?go-get=1": dial tcp 216.239.37.1:443: i/o timeout

GORPOXY只适用于go mod

需要先移动Gopkg.lock

1mv Gopkg.lock Gopkg.lock.bak

然后执行

1go mod init jlb
2go mod tidy

读取配置文件

注: Configuration 里元素(Path)必须大写开头

 1import (
 2    "encoding/json"
 3    "flag"
 4    "fmt"
 5    "io/ioutil"
 6)
 7
 8type Configuration struct {
 9    Path string
10}
11
12const VETSION = "0.1.0"
13
14var (
15    config Configuration
16)
17
18func init() {
19    var (
20        conf_file string
21        print_ver bool
22    )
23    flag.StringVar(&conf_file, "c", "etc/config.json", "config file")
24    flag.BoolVar(&print_ver, "v", false, "config file")
25    flag.Parse()
26
27    raw, err := ioutil.ReadFile(conf_file)
28    if err != nil {
29        log.Error("config parse fail!")
30        os.Exit(1)
31    }
32    err = json.Unmarshal(raw, &config)
33    if err != nil {
34        log.Error("config unmarshal fail!")
35        os.Exit(1)
36    }
37    if print_ver {
38        fmt.Println("version:", VERSION)
39        os.Exit(0)
40    }
41}

判断文件是否存在

 1import (
 2    "os"
 3)
 4func file_is_exists(f string) bool {
 5    _, err := os.Stat(f)
 6    if os.IsNotExist(err) {
 7        return false
 8    }
 9    return err == nil
10}

随机睡眠

1import (
2    "math/rand"
3    "time"
4)
5func random_sleep(t int) {
6    rand.Seed(time.Now().Unix())
7    time.Sleep(time.Duration(rand.Intn(t)) * time.Microsecond)
8}

字符串

随机的n位字符串

 1var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
 2
 3func randStringRunes(n int) string {
 4    rand.Seed(time.Now().UnixNano())
 5    b := make([]rune, n)
 6    for i := range b {
 7        b[i] = letterRunes[rand.Intn(len(letterRunes))]
 8    }
 9    return string(b)
10}

字符串连接

 1import (
 2    "bytes"
 3)
 4func string_concat(s ...string) string {
 5    var buffer bytes.Buffer
 6    for _, i := range s {
 7        buffer.WriteString(i)
 8    }
 9    return buffer.String()
10}

打印原始字符(换行符)

1import (
2    "bytes"
3)
4func print_text(s) string {
5    fmt.Printf("%#v\n", s)
6}

检查元素是否在map中

1func check_in_map(f map[string]string, v string) bool {
2    if _, ok := f[v]; ok {
3        return true
4    }
5    return false
6}

检查元素是否在list中

1func check_in_list(f []string, v string) bool {
2    for i := range f {
3        if f[i] == v {
4            return true
5        }
6    }
7    return false
8}

执行Linux命令

 1import (
 2    "os/exec"
 3)
 4func exec_command(command string, args ...string) (error, bool) {
 5    var (
 6        err error
 7    )
 8    cmd := exec.Command(command, args...)
 9    cmd.Start()
10    done := make(chan error)
11    go func() {
12        done <- cmd.Wait()
13    }()
14
15    select {
16    case <-time.After(600 * time.Second):
17        if err = cmd.Process.Kill(); err != nil {
18            log.Error("failed to kill: %s, error: %s", cmd.Path, err)
19        }
20        go func() {
21            <-done // allow goroutine to exit
22        }()
23        log.Info("process:%s killed", cmd.Path)
24        return err, true
25    case err = <-done:
26        return err, false
27    }
28}

迭代文件目录

 1func file_iter(path string) []string {
 2    // path must be abs path
 3    var files []string
 4    scripts, _ := ioutil.ReadDir(path)
 5    for _, script := range scripts {
 6        if script.IsDir() {
 7            return file_iter(filepath.Join(path, script.Name()))
 8        }
 9        files = append(files, filepath.Join(path, script.Name()))
10    }
11    return files
12}

求两列表的差集

 1func difference(a,b []string) []string {
 2    // len(a) < len(b), avoid all item of a belong to b
 3    m := map[string]bool{}
 4    for _, x := range a {
 5        m[x] = true
 6    }
 7    diff := []string{}
 8    for _, x := range b {
 9        if _, ok := m[x]; !ok {
10            diff = append(diff, x)
11        }
12    }
13    return diff
14}

删除列表中重复的数据

 1func RemoveDuplicates(elements []string) []string {
 2    keys := map[string]bool{}
 3    result := []string{}
 4
 5    for _, element := range elements {
 6        if _, value := keys[element]; !value {
 7            keys[element] = true
 8            result = append(result, element)
 9        }
10    }
11    return result
12}

参数校验

是否是IP

1func IsValidIP(key string) bool {
2    IP := net.ParseIP(key)
3    if IP == nil {
4        return false
5    }
6
7    return true
8}

是否是EMAIL

 1import "regexp"
 2
 3func IsValidEmail(key string) bool {
 4    re := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
 5    if !re.MatchString(key) {
 6        return false
 7    }
 8    if strings.HasSuffix(key, "@upai.com") || strings.HasSuffix(key, "@huaban.com") {
 9        return true
10    }
11    return false
12}

读取http响应的gz package

 1func main() {
 2    resp, _ := HTTPRequest("GET", "http://some-gz-package/package-name", nil)
 3    defer resp.Body.Close()
 4
 5    gz, err := gzip.NewReader(resp.Body)
 6    if err != nil {
 7        fmt.Println(err.Error())
 8        return
 9    }
10    defer gz.Close()
11    scanner := bufio.NewScanner(gz)
12    for scanner.Scan() {
13        fmt.Println(scanner.Text())
14    }
15}

编译

编译成不同系统的可执行文件

  • GOOS:目标可执行程序运行操作系统,支持 darwin,freebsd,linux,windows

  • GOARCH:目标可执行程序操作系统构架,包括 386,amd64,arm

    1# Golang version 1.5以前版本在首次交叉编译时还需要配置交叉编译环境:
    2CGO_ENABLED=0 GOOS=linux GOARCH=amd64 ./make.bash
    3CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash
  1. Mac下编译Linux, Windows平台的64位可执行程序:

    1$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build test.go
    2$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
  2. Linux下编译Mac, Windows平台的64位可执行程序:

    1$ CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build test.go
    2$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
  3. Windows下编译Mac, Linux平台的64位可执行程序:

    1$ SET CGO_ENABLED=0SET GOOS=darwin3 SET GOARCH=amd64 go build test.go
    2$ SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build test.go

测试

指定函数

  • test

    1go test -run="^TestAAA" ./...
  • bench

    1go test -bench="^BenchmarkAAA" -run="^Benchmark" ./...

常见问题

docker内运行时区问题

解决方式

1apt-get install -y tzdata

map性能

1只读场景:sync.map > rwmutex >> mutex
2读写场景(边读边写):rwmutex > mutex >> sync.map
3读写场景(读80% 写20%):sync.map > rwmutex > mutex
4读写场景(读98% 写2%):sync.map > rwmutex >> mutex
5只写场景:sync.map >> mutex > rwmutex

go mod tidy checking tree against

https://github.com/golang/go/issues/35164

 1 go mod tidy
 2go: finding module for package github.com/honmaple/org-golang
 3go: finding module for package github.com/honmaple/org-golang/render
 4go: downloading github.com/honmaple/org-golang v0.0.0-20230214143528-22f61b3874c8
 5github.com/honmaple/snow/builder/page/markup/orgmode imports
 6    github.com/honmaple/org-golang: github.com/honmaple/org-golang@v0.0.0-20230214143528-22f61b3874c8: verifying module: github.com/honmaple/org-golang@v0.0.0-20230214143528-22f61b3874c8: checking tree#15584694 against tree#15683659: reading https://goproxy.io/sumdb/sum.golang.org/tile/8/1/237: 404 Not Found
 7    server response: not found
 8github.com/honmaple/snow/builder/page/markup/orgmode imports
 9    github.com/honmaple/org-golang/render: github.com/honmaple/org-golang@v0.0.0-20230214143528-22f61b3874c8: verifying module: github.com/honmaple/org-golang@v0.0.0-20230214143528-22f61b3874c8: checking tree#15584694 against tree#15683659: reading https://goproxy.io/sumdb/sum.golang.org/tile/8/1/237: 404 Not Found
10    server response: not found
1 GOSUMDB=off go mod tidy
2go: finding module for package github.com/honmaple/org-golang
3go: finding module for package github.com/honmaple/org-golang/render
4go: downloading github.com/honmaple/org-golang v0.0.0-20230214143528-22f61b3874c8
5go: found github.com/honmaple/org-golang in github.com/honmaple/org-golang v0.0.0-20230214143528-22f61b3874c8
6go: found github.com/honmaple/org-golang/render in github.com/honmaple/org-golang v0.0.0-20230214143528-22f61b3874c8
作者: honmaple
链接: https://honmaple.me/articles/2018/03/golang笔记.html
版权: CC BY-NC-SA 4.0 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat
alipay

加载评论