go 用法

查看文档

go doc time

go doc hello.HelloReply

 

stringer 

自动将常量转换成相应的字符串

 

原理

将相关的常量转换为 同一种类型

并给这个类型加上 String() 函数, 这样调用 fmt.Print 之类的函数就会 自动调用 String() 转换成相应的字符串了

 

有了 go mod 和 proxy 再也不用墙了

go get -u golang.org/x/tools/cmd/stringer

 

示例

main.go

//go:generate stringer -type=CID

package main

import "fmt"

//go:generate stringer -type=CID
// 注意//与go:generate字符之间不能有空格
type CID byte

const (
	LinkCheckReq CID = 0x02
	LinkCheckAns CID = 0x03
	LinkADRReq   CID = 0x04
	LinkADRAns   CID = 0x05
)

func main() {
	fmt.Println(LinkADRAns)
}

 

$ go generate

这样在同目录下会生成 cid_string.go

~/gol $ go run main.go cid_string.go
LinkADRAns

 

性能分析

https://github.com/caibirdme/hand-to-hand-optimize-go

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/feixiao/httpprof"
	"github.com/julienschmidt/httprouter"
)

func main() {
	router := httprouter.New()

	log.Fatal(http.ListenAndServe(":8080", httpprof.WrapRouter(router)))
}

http://localhost:8080/debug/pprof/ 就可以访问 分析项目

 

once

func demo1() {
	var once sync.Once
	var wg sync.WaitGroup
	say := func() { fmt.Println("hello") }

	// 无论你折腾几回 once 变量确保了 say 只被调用一回
	wg.Add(2)
	go func(o *sync.Once) { o.Do(say); wg.Done() } (&once)
	go func() { once.Do(say); wg.Done() } ()
	once.Do(say)
	wg.Wait()
}

 

同步

startChan := make(chan bool)
go somefunc(startChan)
<-startChan

func somefunc(start chan) {
     ... 干你想干的事 ...
     // 通知 调用方, 我已经启动好了
     close(start)
     ...
}

for select 内部的 continue 和 break

// for select 内部的 continue 和 break
func demo5Worker(wg *sync.WaitGroup, c1 chan bool, c2 chan bool) {
	defer wg.Done()
	var done bool
	for {
		select {
		case <- c1:
			fmt.Println("recived c1")
			continue // select 内部没有 continue, continue 是跳到了  for 的下一次循环
			// 将不会到达  fmt.Println("work after select") 那一行
		case <- c2:
			fmt.Println("recived c2")
			done = true
			// select 内部有 break  
			break // 这个break 仅仅跳出了 select 
			// 接下去就到了  fmt.Println("work after select") 那一行
			// 想跳出 for 中的 select 你得 goto  return 或者 像我例子一样搞个变量
		}

		fmt.Println("work after select")
		if done {
			break
		}
	}
}

 

正则 regexp
https://blog.csdn.net/tennysonsky/article/details/79081524

 

defer 是以函数为范围的
{} 结束时 是不会调用的

 

sync.Pool
是减少垃圾回收次数的,不是保存数据的

 

select  和c语言不同 不 roll down
default 当 case 们都不能马上执行的时候调用

channel 多个goroutine 同时等待 channel, 等到的goroutine是随机的,
不是先等就可以先获得

 

执行程序 获取输出

b, err := exec.Command("uname", "-a").Output()

 

动态条件 占用 cpu 数量

AutoGOMAXPROCS()

 

附带 调用堆栈, 到 codis 代码里抄的

func TraceN(skip, depth int) Stack {
	s := make([]*Record, 0, depth)
	for i := 0; i < depth; i++ {
		r := Caller(skip + i + 1)
		if r == nil {
			break
		}
		s = append(s, r)
	}
	return s
}

func Caller(skip int) *Record {
	pc, file, line, ok := runtime.Caller(skip + 1)
	if !ok {
		return nil
	}
	fn := runtime.FuncForPC(pc)
	if fn == nil || strings.HasPrefix(fn.Name(), "runtime.") {
		return nil
	}
	return &Record{
		Name: fn.Name(),
		File: file,
		Line: line,
	}
}

 

debug

go get github.com/go-delve/delve/cmd/dlv

help 查看 所有命令

dlv debug ./main.go

b main.main
c 运行到断点

b /home/goworkspace/src/github.com/mytest/main.go:20

调试已经运行的程序
dlv attach pid
要把 ptrace_scope 的值设置为0
第一次运行的时候要先 c-f c-x 下
(op "/sudo:localhost:/proc/sys/kernel/yama/ptrace_scope")

 

go plugin

用go生成go的动态库   c语言的动态库 给别的程序调用等等

http://www.361way.com/go-plugin/5925.html

 

string []byte 相互转换

[]byte("hello")
string([]byte{99,98,97}) // cba

func Slice(s string) (b []byte) {
	pb := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	ps := (*reflect.StringHeader)(unsafe.Pointer(&s))
	pb.Data, pb.Len, pb.Cap = ps.Data, ps.Len, ps.Len
	return
}

func String(b []byte) string {
	// strings.Builder String() 的源码
	return *(*string)(unsafe.Pointer(&b))
}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值