Go

Go 学习笔记

Posted by API Caller on March 31, 2019

最近常和人安利 Go 是最简单的语言之一, 但实际上也是有 cgo 的存在, 记录一些关于指针或者 cgo 或者其它等等的片段.

获得二维数组行列数

1
2
3
4
5
6
7
8
9
	arr := [][]int{
		{1, 1},
		{2, 2},
		{3, 3},
		{4, 4},
	}

	fmt.Println((*reflect.SliceHeader)(unsafe.Pointer(&arr)).Len)
	fmt.Println((*reflect.SliceHeader)(unsafe.Pointer(&arr[0])).Len)

defer 01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type number int

func (n number) print()   { fmt.Println(n) }
func (n *number) pprint() { fmt.Println(*n) }

func main() {
	var n number

	defer n.print()
	defer n.pprint()
	defer func() { n.print() }()
	defer func() { n.pprint() }()

	n = 3
}

struct -> slice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
type MyStruct struct {
	A int
	B int
}

var sizeOfMyStruct = int(unsafe.Sizeof(MyStruct{}))

func MyStructToBytes(s *MyStruct) []byte {
	var x reflect.SliceHeader
	x.Len = sizeOfMyStruct
	x.Cap = sizeOfMyStruct
	x.Data = uintptr(unsafe.Pointer(s))
	return *(*[]byte)(unsafe.Pointer(&x))
}

func BytesToMyStruct(b []byte) *MyStruct {
	return (*MyStruct)(unsafe.Pointer(
		(*reflect.SliceHeader)(unsafe.Pointer(&b)).Data,
	))
}

func main() {
	v1 := MyStruct{7, 8}
	
	fmt.Println(MyStructToBytes(&v1))

	fmt.Println((*[1000]byte)(unsafe.Pointer(&v1))[:sizeOfMyStruct])

}

network

http/s 代理

1
2
3
4
5
http.ProxyURL(&url.URL{
	Scheme:	"http",
	Host:	"127.0.0.1:8888",
	Path:	"/",
})

websocket 使用代理(socks5)

如果使用 Charles 的 http 代理, Scheme 也被改成了 http/s 了.

1
2
3
4
5
6
netDialer, _ := proxy.SOCKS5("tcp", "127.0.0.1:8889", nil, proxy.Direct)

d := websocket.Dialer(NetDial: netDialer.Dial)

// d.Dial(url....)

heartbeat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
	ctx, cancel := context.WithCancel(context.TODO())

	go func() {

		tickerHeartBeat := time.NewTicker(time.Second * 20)
		defer tickerHeartBeat.Stop()

		for {
			select {
			case <-ctx.Done():
				return
			case <-done:
				return
			case <-tickerHeartBeat.C:
				err := HeartBeat() // ping
				if err != nil {
					log.Println("HeartBeat:", err)
					return
				}
			case <-interrupt:
				log.Println("interrupt")
				err := CloseMessage()
				if err != nil {
					log.Println("write close:", err)
					return
				}
				select {
				case <-ctx.Done():
				case <-done:
				case <-time.After(time.Second):
				}
				return
			}
		}
	}()

	defer cancel()

类型断言

golang ensure interface implement compile time - Google Search

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type HelloServiceClient struct {
	*rpc.Client
}

type HelloServiceInterface = interface {
	Hello(request string, reply *string) error
}

/**
type T struct{}
var _ I = T{}
其中 I 为interface. 上面用来判断 type T 是否实现了 I, 用作类型断言, 如果 T 没有实现接口 I, 则编译错误
 */
var _ HelloServiceInterface = (*HelloServiceClient)(nil)