go备忘

0、Go语言 IDE之Gogland配置使用
https://www.cnblogs.com/yangxiaoyi/p/6422033.html

1、Go 包依赖管理工具 —— govendor (可以升级使用 go mudle 了)
govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具。与原生 vendor 无侵入性融合,也支持从其他依赖管理工具迁移,可以很方便的实现同一个包在不同项目中不同版本、以及无相互侵入的开发和管理。
https://shockerli.net/post/go-package-manage-tool-govendor/

2、Golang 大杀器之性能剖析 PProf
https://segmentfault.com/a/1190000016412013

https://blog.golang.org/profiling-go-programs

Go 程序的性能优化及 pprof 的使用
https://www.cnblogs.com/snowInPluto/p/7403097.html
示例程序

package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"

	_ "net/http/pprof"
)

func main() {
	http.HandleFunc("/test", handler)
	log.Fatal(http.ListenAndServe(":9876", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if nil != err {
		w.Write([]byte(err.Error()))
		return
	}
	doSomeThingOne(10000)
	buff := genSomeBytes()
	b, err := ioutil.ReadAll(buff)
	if nil != err {
		w.Write([]byte(err.Error()))
		return
	}
	w.Write(b)
}

func doSomeThingOne(times int) {
	for i := 0; i < times; i++ {
		for j := 0; j < times; j++ {

		}
	}
}

func genSomeBytes() *bytes.Buffer {
	var buff bytes.Buffer
	for i := 1; i < 20000; i++ {
		buff.Write([]byte{'0' + byte(rand.Intn(10))})
	}
	return &buff
}

3、开源库查询网站
https://golanglibs.com/

官方维护的开源库wiki
https://github.com/golang/go/wiki/Projects

4、Go net包介绍
体验代码如下:

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    addr, err := net.ResolveIPAddr("ip", "www.baidu.com")
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    fmt.Println(addr.IP)

https://blog.csdn.net/cc7756789w/article/details/51014076

5、go开发者手册
https://cloud.tencent.com/developer/section/1143773

6、Go语言中的strcut tag
在struct中的每一个field后面添加一段额外的注释或者说明,来引导struct的encoding到某种格式中,这部分额外的注释说明,我们称之为struct中的field tag,比如:

type Person struct {
    FirstName  string `json:"first_name"`
    LastName   string `json:"last_name"`
    MiddleName string `json:"middle_name,omitempty"`
}

https://zhuanlan.zhihu.com/p/32279896

7、Go by Example: Goroutines

package main

import (
    "fmt"
    "time"
)

func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {

    f("direct")

    go f("goroutine")

    go func(msg string) {
        fmt.Println(msg)
    }("going")

    time.Sleep(time.Second)
    fmt.Println("done")
}

https://gobyexample.com/goroutines

//通过下面函数理解协程执行:当屏蔽time.Sleep(10)时,go func in main不会被打印,因为func main执行结束,导致go func的内容没有被打印出来
package main

import (
	"fmt"
)

func main() {
	fmt.Println("func main: begin")
    go func() {
		for i := 0; i < 10; i++ {
			fmt.Println("go func in main:", i)
		}
	}()
    //time.Sleep(10)
	fmt.Println("func main: end")
}

https://gobyexample.com/range
Go by Example: Range

package main

import "fmt"

func main() {

    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)

    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }

    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }

    for k := range kvs {
        fmt.Println("key:", k)
    }

    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

8、Go语言通道(chan)——goroutine之间通信的管道
如果说 goroutine 是 Go语言程序的并发体的话,那么 channels 就是它们之间的通信机制。一个 channels 是一个通信机制,它可以让一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个特殊的类型,也就是 channels 可发送数据的类型。一个可以发送 int 类型数据的 channel 一般写为 chan int。
在这里插入图片描述
示例代码:

package main

import (
    "fmt"
)

func main() {

    // 构建一个通道
    ch := make(chan int)

    // 开启一个并发匿名函数
    go func() {

        fmt.Println("start goroutine")

        // 通过通道通知main的goroutine
        ch <- 0

        fmt.Println("exit goroutine")

    }()

    fmt.Println("wait goroutine")

    // 等待匿名goroutine
    <-ch

    fmt.Println("all done")

}

执行代码,输出如下:
wait goroutine
start goroutine
exit goroutine
all done

代码说明如下:
第 10 行,构建一个同步用的通道。
第 13 行,开启一个匿名函数的并发。
第 18 行,匿名 goroutine 即将结束时,通过通道通知 main 的 goroutine,这一句会一直阻塞直到 main 的 goroutine 接收为止。
第 27 行,开启 goroutine 后,马上通过通道等待匿名 goroutine 结束。
http://c.biancheng.net/view/97.html

28、通过channel实现2进程间双向通信

package main

import (
	"fmt"
)

func testChan(c, quit chan int) {
    x := 1
    for {
        select {
        case c <- x:
            x += 1
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}
func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("go func in main:", <-c)
        }
        quit <- 0
    }()
	testChan(c, quit)
}

https://leokongwq.github.io/2016/10/15/golang-chan.html

29、【Go 语言社区】golang协程——通道channel阻塞
https://cloud.tencent.com/developer/article/1066252

30、Go并发:利用sync.WaitGroup实现协程同步

package main

import (
    "fmt"
    "sync"
)

func main() {

    var wg sync.WaitGroup

    wg.Add(2) // 因为有两个动作,所以增加2个计数
    go func() {
        fmt.Println("Goroutine 1")
        wg.Done() // 操作完成,减少一个计数
    }()

    go func() {
        fmt.Println("Goroutine 2")
        wg.Done() // 操作完成,减少一个计数
    }()

    wg.Wait() // 等待,直到计数为0
}

https://blog.csdn.net/u011304970/article/details/72722044

31、CGO_ENABLED环境变量对Go静态编译机制的影响
https://johng.cn/cgo-enabled-affect-go-static-compile/#Go-2

32、go的defer用法范例
https://www.jianshu.com/p/7ada9f376e89

33、https://gobyexample.com/maps

package main

import "fmt"

func main() {

    m := make(map[string]int)

    m["k1"] = 7
    m["k2"] = 13

    fmt.Println("map:", m)

    v1 := m["k1"]
    fmt.Println("v1: ", v1)

    fmt.Println("len:", len(m))

    delete(m, "k2")
    fmt.Println("map:", m)

    _, prs := m["k2"]
    fmt.Println("prs:", prs)

    n := map[string]int{"foo": 1, "bar": 2}
    fmt.Println("map:", n)
}

34、Go Modules 不完全教程
(0) 包管理的历史
(1). modules 简单使用方式
https://mp.weixin.qq.com/s/v-NdYEJBgKbiKsdoQaRsQg##

34、10分钟学会go module
https://blog.csdn.net/e421083458/article/details/89762113

35、Golang关键字–type 类型定义
https://www.jianshu.com/p/a02cf41c0520
为什么要使用类型定义呢?类型定义可以在原类型的基础上创造出新的类型,有些场合下可以使代码更加简洁。

36、golang fmt格式化字符串%v,%T
https://blog.csdn.net/lanyang123456/article/details/78172375

%v the value in a default format
when printing structs, the plus flag (%+v) adds field names
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the value
package main

import (

        "fmt"
)


type Power struct{
        age int
        high int
        name string
}

func main() {

        var i Power = Power{age: 10, high: 178, name: "NewMan"}

        fmt.Printf("type:%T\n", i)
        fmt.Printf("value:%v\n", i)
        fmt.Printf("value+:%+v\n", i)
        fmt.Printf("value#:%#v\n", i)


        fmt.Println("========interface========")
        var interf interface{} = i
        fmt.Printf("%v\n", interf)
        fmt.Println(interf)
}

37、go import使用及. _的作用解析
https://www.cnblogs.com/baiyuxiong/p/4440581.html

goimport用于导入包。导入之后就可以使用包中的代码。

比如:
import(
"fmt"
)
在代码中就可以使用fmt包中的方法,如:
fmt.Println("hello world")

1、使用点操作引入包时,可以省略包前缀:
import(
. "fmt"
)
注意上面 fmt前多了 . 字符。代码中使用时:
Println("hello world")
前缀fmt就不需要了。

2、别名操作可以给包起个小名儿。如:
import(
f "fmt"
)
f.Println("hello world")

3_操作
由于go在引入包时调用包的init方法。所以使用_操作,主要是为了使用包的init函数,一般用在数据库方面的包中:

import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
这个可以避免go编译时提示引入了包但未使用。

38、ssl证书找不到,解决办法

fatal: unable to access 'https://code.*****/xx.git/': Peer's Certificate issuer is not recognized.
或者  SSL certificate problem: unable to get local issuer certificate

提示SSL证书错误。后面用谷歌搜索了一下,发现说这个错误并不重要是系统证书的问题,系统判断到这个行为会造成不良影响,所以进行了阻止,只要设置跳过SSL证书验证就可以了,那么用命令 :

git config --global http.sslVerify false

参考:https://blog.csdn.net/fenglailea/article/details/50041219

39、go module无法下载golang.org/x
解决办法replace:

go mod edit -replace=golang.org/x/sys@v0.0.0-20190222072716-a9d3bda3a223=github.com/golang/sys@latest

https://blog.csdn.net/wz122330/article/details/89493467

30、Go Modules介绍
Go Modules介绍
Modules是 Go 1.11中新增的实验性功能,基于vgo演变而来,是一个新型的包管理工具。
(说明:Go has included support for versioned modules as proposed here since 1.11. The initial prototype vgo was announced in February 2018. In July 2018, versioned modules landed in the main Go repository.
In Go 1.14, module support will be considered ready for production use, and all users will be encouraged to migrate to modules from other dependency management systems.
https://github.com/golang/go/wiki/Modules)

常见的包管理工具
govendor
dep
glide
godep
这些包管理 工具 都是基于 GOPATH 或者 vendor 目录,并不能很好的解决不同版本依赖问题。Modules是在 GOPATH 之外一套新的包管理方式。

go mod不同于以往基于GOPATH和Vendor的构建方式,其主要是通过GOPATH/pkg/mod下的缓存包来对工程进行构建。在Go 1.11中已经可以使用,同以往新添加的功能一样,go mod 可以通过GO111MODULE来控制是否启用,GO111MODULE有一下三种类型。

on 所有的构建,都使用Module机制
off 所有的构建,都不使用Module机制,而是使用GOPATH和Vendor
auto 在GOPATH下的工程,不使用Module机制,不在GOPATH下的工程使用

试一下:
首先创建一个项目helloworld:

cd && mkdir helloworld && cd helloworld
然后创建文件 main.go 并写入:

package main

import (
    log "github.com/sirupsen/logrus"
)

func main() {
    log.WithFields(log.Fields{
        "animal": "walrus",
    }).Info("A walrus appears")
}

初始化mod:

go mod init helloworld
系统生成了一个 go.mod 的文件:

module helloworld
然后执行go build,再次查看go.mod文件发现多了一些内容:
module helloworld
执行./helloworld

31、拜拜了,GOPATH君!新版本Golang的包管理入门教程
https://juejin.im/post/5c9c8c4fe51d450bc9547ba1

package main
import "github.com/astaxie/beego"
func main() {
    beego.Run()
}

32、Go mod使用实践(被引入.go文件和引入.go文件处于同一项目不同目录下)
32.1未使用go mod前,当前工程路径和GOPATH为workspace/testmod,即当前工程的结构如下:

├── bin
├── pkg
└── src
    ├── api
    │   └── supply
    │       └── location
    │           └── location.go
    └── main.go

location.go

package location

import (
        "fmt"
)

func Hi(name string) string {
        return fmt.Sprintf("hello %s",name)
}

在main.go中引用location.go时,import中路径为"api/supply/location"。

package main

import(
        "api/supply/location"
        "fmt"
)

func main() {
        fmt.Println(location.Hi("test"))
}

32.2 使用go mod后
当前工程路径为workspace/testmod,在src目录下执行go mod init testmod后,在main.go中引用location.go时,import中路径需要变更为"testmod/api/supply/location",否则编译时会报错build command-line-arguments: cannot load api/supply/location: cannot find module providing package api/supply/location

执行

go mod init testmod

生成go.mod文件

module testmod

go 1.12

main.go

package main

import(
        "fmt"
        "testmod/api/supply/location"
)

func main() {
        fmt.Println(location.Hi("test"))
}

执行go build拉去依赖并编译。(此示例中并没有依赖其他任何包,仅示意:使能go modules;A.go文件调用同一项目不同目录下的B.go文件)

使用GoLang IDE调试代码,注意确认“Enable Go Modules(vgo) integration”
在这里插入图片描述

参考:(1) go1.12下Go mod使用实践 https://studygolang.com/articles/21265
(2) go package、import、go.mod 理解 以及 私有包引入
https://blog.csdn.net/zhetmdoubeizhanyong/article/details/100569182
(3) goland import 当前工程文件,无法识别
https://bbs.csdn.net/topics/395241465

33、Creating a project with Go modules (vgo)
https://www.jetbrains.com/help/go/create-a-project-with-vgo-integration.html#

34、Go 模块使用指南
https://blog.jetbrains.com/cn/2019/03/go-%E6%A8%A1%E5%9D%97%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/

35、谈谈go.sum
go.sum 看上去就是 go module 构建出来的天书
https://studygolang.com/articles/25658

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值