首页 > 技术文章 > go工具

double12gzh 2019-08-17 23:05 原文

以一个简单的例子说明一下go中比较有用的小工具

1. 小工具

1.1 生成一个main.go脚本

jeffreyguan@localhost ~$ cat > main.go
package main
import "fmt"
func main() { fmt.Println("Hello, Jeffrey Guan") }

jeffreyguan@localhost ~$ cat main.go                                                                                                                  130 ↵
package main
import "fmt"
func main() { fmt.Println("Hello, Jeffrey Guan") }

1.2. gofmt main.go

jeffreyguan@localhost ~$ gofmt main.go
package main

import "fmt"

func main() { fmt.Println("Hello, Jeffrey Guan") }

1.3. gofmt -d main.go

jeffreyguan@localhost ~$ gofmt -d main.go
diff -u main.go.orig main.go
--- main.go.orig	2019-08-17 21:42:13.000000000 +0800
+++ main.go	2019-08-17 21:42:13.000000000 +0800
@@ -1,5 +1,5 @@
 package main
-import "fmt"
-func main() { fmt.Println("Hello, Jeffrey Guan") }

+import "fmt"

+func main() { fmt.Println("Hello, Jeffrey Guan") }

1.4. gofmt -w main.go

jeffreyguan@localhost ~$ gofmt -w main.go

jeffreyguan@localhost ~$ cat main.go
package main

import "fmt"

func main() { fmt.Println("Hello, Jeffrey Guan") }

1.5. go build

go build flags:
https://lukeeckley.com/post/useful-go-build-flags/
debug与release版本
https://dave.cheney.net/2014/09/28/using-build-to-switch-between-debug-and-release

jeffreyguan@localhost ~$ go build main.go
jeffreyguan@localhost ~$ file main
main: Mach-O 64-bit executable x86_64

按平台生成可执行文件

jeffreyguan@localhost ~$ GOOS=windows go build main.go

jeffreyguan@localhost ~$ file main.exe
main.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

是否开启debug log和release log打印
main.go

package main

func main() {

	Debug("It's expensive")

}

log_debug.go

//+build debug

package main

import "fmt"

func Debug(a ...interface{}) {
	fmt.Println(a...)
}

log_release.go

//+build !debug

package main

func Debug(a ...interface{}) {}

开启debuglog
go build -tags "debug"

不开启
go build

1.6. go get

go get github.com/golang/example/hello

1.7. go list

jeffreyguan@localhost ~/lanjie$ cat main.go
// demo is also demo
package main

import "fmt"

func main() { fmt.Println("Hello, Jeffrey Guan") }
jeffreyguan@localhost ~/lanjie$ go list -f '{{ .Name }}'
main
jeffreyguan@localhost ~/lanjie$ go list -f '{{ .Name }}: {{ .Doc}}'
main: demo is also demo
jeffreyguan@localhost ~/lanjie$ go list -f '{{ .Name }}: {{ .Doc}}'
main: demo is also demo
jeffreyguan@localhost ~/lanjie$ go list -f '{{ .Imports }}'
[fmt]
jeffreyguan@localhost ~/lanjie$ go list -f '{{ join .Imports "\n"}}' fmt
errors
internal/fmtsort
io
math
os
reflect
strconv
sync
unicode/utf8
jeffreyguan@localhost ~/lanjie$ go list -f '{{ .Doc }}' fmt
Package fmt implements formatted I/O with functions analogous to C's printf and scanf.

1.8. do doc

jeffreyguan@localhost ~/lanjie$ go doc fmt
jeffreyguan@localhost ~/lanjie$ go doc fmt Println
func Println(a ...interface{}) (n int, err error)
    Println formats using the default formats for its operands and writes to
    standard output. Spaces are always added between operands and a newline is
    appended. It returns the number of bytes written and any write error
    encountered.

# 在本地启动go doc
jeffreyguan@localhost ~/lanjie$ godoc -http=localhost:6060

1.9 errcheck

1.10 go vet

1.11 go-wrk

1.12 go tool pprof

https://segmentfault.com/a/1190000016412013
https://www.infoq.cn/article/f69uvzJUOmq276HBp1Qb

1.13 go-torch

1.14 go tool trace

https://segmentfault.com/a/1190000019736288

2. 通过go启动web服务

3. golang中常用的库

3.1 mapstructure: 解析未知结构的yaml、json

示例

package main

import (
	"encoding/json"
	"fmt"
	"github.com/mitchellh/mapstructure"

	"gopkg.in/yaml.v2"
)


const (
	test_yaml = `
extraImageList:
  - registry: repository_xx
    name: image_name_xx
    tag: image_tag_xx

  - registry: repository_yy
    name: image_name_yy
    tag: image_tag_yy

image:
  registry: registry_zz
  name: name_zz
  tag: tag_zz`

	test_json = `
{
  "extraImageList": [
    {
      "registry": "xxxx",
      "name": "fuck",
      "tag": "aaaa"
    },
    {
      "registry": "yyy",
      "name": "fuck2",
      "tag": "bbbb"
    }
  ],
  "image": {
    "registry": "abab",
    "name": "cdcd",
    "tag": 1
  }
}
`
)

type MyImage struct {
	ExtraImageList []Image `yaml:"extraImageList" json:"extraImageList" mapstructure:"extraImageList"`
	Image Image `yaml:"image" json:"image" mapstructure:"image"`
}

type Image struct {
	Registry string `yaml:"registry" json:"registry" mapstructure:"registry"`
	Name string `yaml:"name" json:"name" mapstructure:"name"`
	Tag string `yaml:"tag" json:"tag" mapstructure:"tag"`
	Repository string `mapstructure:"repository"`
}

type NewMyImage struct {
	ExtraImageList []Image `yaml:"extraImageList" json:"extraImageList" mapstructure:"extraImageList"`
	Image Image `yaml:"image" json:"image" mapstructure:"image"`
	TestImage string `mapstructure:"testimage"`
	ImageList []Image `mapstructure:"imagelist"`
}

func main() {
	// yaml解析
	tempExtra := MyImage{}
	//cont, _ := ioutil.ReadFile("test.yaml")
	//yaml.Unmarshal(cont, &tempExtra)
	
	cont := test_yaml
	yaml.Unmarshal([]byte(cont), &tempExtra)
	
	fmt.Printf("yaml: %s\n", tempExtra.ExtraImageList[0].Tag)

	// 打印json字符串
	result, err := json.Marshal(tempExtra)
	if err != nil {
		panic(err)
	}

	fmt.Printf("json: %s\n", result)

	// mapstructure解析
	var myImage NewMyImage
	var tempImage2 map[string]interface{}

	//newCont2, _ := ioutil.ReadFile("test.json")
	//json.Unmarshal(newCont2,&tempImage2)
	
	newCont2 := test_json
	json.Unmarshal([]byte(newCont2),&tempImage2)

	if err := mapstructure.WeakDecode(tempImage2, &myImage); err != nil {
		panic(err)
	}

	fmt.Printf("mapstructure: %#v", myImage.Image)
}

3.2 viper: 解析yaml, json, ini, toml

3.3 gjsonq: golang中的jsonpath

3.4 (Mergo)[https://github.com/imdario/mergo]

3.5 GODEBUG=gctrace=1000

参考1
参考2
参考3

推荐阅读