Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go #9

Open
gobomb opened this issue Sep 23, 2019 · 22 comments
Open

go #9

gobomb opened this issue Sep 23, 2019 · 22 comments

Comments

@gobomb
Copy link
Owner

gobomb commented Sep 23, 2019

打印结构体%v``%+v``%#v的区别

针对结构体
%v 打印字段的值
%+v 打印字段的名字和字段的值
%#v 按照go中结构体的格式打印(打印结构体的名字,字段的名字和值)
如果字段是指针,值就是指针地址。
可以给结构体实现一个 String() string方法自定义打印的格式(从而打印指针对应的内容)。对%v和%+v生效,对%#v不生效。

实现了String()string 意味着实现了fmt.Stringer。fmt包中 %v%+v会检查参数实现了error或者Stringer,从而调用errror()或者String()。

%#v则需要实现 GoString()string 方法来自定义。

实现 fmt.Formatter 可做到更加灵活的格式控制。github.com/pkg/errors 就是用这种方式输出调用栈。可获取到 fmt.State 进行写,verb 判断占位符。

@gobomb
Copy link
Owner Author

gobomb commented Feb 27, 2020

https://go101.org/article/channel-closing.html

关闭channel的方法

@gobomb
Copy link
Owner Author

gobomb commented Feb 27, 2020

@gobomb
Copy link
Owner Author

gobomb commented Mar 24, 2020

限制goroutine的数量

package gpool

import (
	"sync"
)

type pool struct {
	queue chan int
	wg    *sync.WaitGroup
}

func New(size int) *pool {
	if size <= 0 {
		size = 1
	}
	return &pool{
		queue: make(chan int, size),
		wg:    &sync.WaitGroup{},
	}
}

func (p *pool) Add(delta int) {
	for i := 0; i < delta; i++ {
		p.queue <- 1
	}
	for i := 0; i > delta; i-- {
		<-p.queue
	}
	p.wg.Add(delta)
}

func (p *pool) Done() {
	<-p.queue
	p.wg.Done()
}

func (p *pool) Wait() {
	p.wg.Wait()
}
package gpool_test

import (
	"runtime"
	"testing"
	"time"
	"gpool"
)

func Test_Example(t *testing.T) {
	pool := gpool.New(100)
	println(runtime.NumGoroutine())
	for i := 0; i < 1000; i++ {
		pool.Add(1)
		go func() {
			time.Sleep(time.Second)
			println(runtime.NumGoroutine())
			pool.Done()
		}()
	}
	pool.Wait()
	println(runtime.NumGoroutine())
}

ref: https://my.oschina.net/xlplbo/blog/682884

@gobomb
Copy link
Owner Author

gobomb commented Jul 30, 2020

grpcui -plaintext -bind 0.0.0.0 -proto proto/orca.proto 10.10.13.7:1400

grpc 调试工具(类似postman之于http)

https://github.com/fullstorydev/grpcui

@gobomb
Copy link
Owner Author

gobomb commented Sep 12, 2020

go mod 系列博客阅读笔记

https://blog.golang.org/using-go-modules

  1. Starting in Go 1.13, module mode will be the default for all development.

  2. The indirect comment indicates a dependency is not used directly by this module, only indirectly by other module dependencies. 

  3. Each different major version (v1, v2, and so on) of a Go module uses a different module path: starting at v2, the path must end in the major version.

  4. go buildgo test, and other package-building commands add new dependencies to go.mod as needed.

    go mod tidy removes unused dependencies.

  5. Note that when go mod tidy adds a requirement, it adds the latest version of the module.

  6. The version referenced in a go.mod may be an explicit release tagged in the repository (for example, v1.5.2), or it may be a pseudo-version based on a specific commit (for example, v0.0.0-20170915032832-14c0d48ead0c). Pseudo-versions are a special type of pre-release version. Pseudo-versions are useful when a user needs to depend on a project that has not published any semantic version tags, or develop against a commit that hasn't been tagged yet, but users should not assume that pseudo-versions provide a stable or well-tested API.

  7. Sometimes, maintaining backwards compatibility can lead to awkward APIs. That's OK. An imperfect API is better than breaking users' existing code.

  8. If an old package and a new package have the same import path, the new package must be backwards compatible with the old package.

  9. Pseudo-versions never need to be typed by hand: the go command will accept the plain commit hash and translate it into a pseudo-version (or a tagged version if available) automatically.

@gobomb
Copy link
Owner Author

gobomb commented Sep 27, 2020

@gobomb
Copy link
Owner Author

gobomb commented Sep 27, 2020

	var slis []*string = []*string{&a, &b, &c}
	for _, s := range slis {
		fmt.Printf("in for:\t %p \t---- %p\n", s, &s)
		//time.Sleep(1 * time.Second)

		go func() {
			fmt.Printf("in func:\t %p \t---- %p\n", s, &s)

		}()
		
		go func(s *string) {
			fmt.Printf("in func(s):\t %p \t---- %p\n", s, &s)

		}(s)
	}

	time.Sleep(2 * time.Second)

goroutine 闭包如果不通过传参的方式使用指针,在for循环中,因为指针会被赋值,是共享的,可能会导致读到了更新过的值。通过参数传递的话,就能够保证每个 goroutine 用了不同的指针。

in for:	 0xc000010250 	---- 0xc00000e030
in for:	 0xc000010260 	---- 0xc00000e030
in for:	 0xc000010270 	---- 0xc00000e030
in func:	 0xc000010260 	---- 0xc00000e030
in func:	 0xc000010270 	---- 0xc00000e030
in func(s):	 0xc000010270 	---- 0xc00000e040
in func:	 0xc000010270 	---- 0xc00000e030
in func(s):	 0xc000010260 	---- 0xc00009e000
in func(s):	 0xc000010250 	---- 0xc000100000

@gobomb
Copy link
Owner Author

gobomb commented Oct 14, 2020

@gobomb
Copy link
Owner Author

gobomb commented Nov 11, 2020

@gobomb
Copy link
Owner Author

gobomb commented Dec 9, 2020

https://blog.chewxy.com/2018/03/18/golang-interfaces/

从使用者定义interface

@gobomb
Copy link
Owner Author

gobomb commented Dec 9, 2020

https://draveness.me/golang-101/

go工程实践

@gobomb
Copy link
Owner Author

gobomb commented Dec 31, 2020

@gobomb
Copy link
Owner Author

gobomb commented Feb 22, 2021

@gobomb
Copy link
Owner Author

gobomb commented Mar 15, 2021

https://blog.golang.org/laws-of-reflection

A variable of interface type stores a pair: the concrete value assigned to the variable, and that value's type descriptor. To be more precise, the value is the underlying concrete data item that implements the interface and the type describes the full type of that item.
...
One important detail is that the pair inside an interface always has the form (value, concrete type) and cannot have the form (value, interface type). Interfaces do not hold interface values.

@gobomb
Copy link
Owner Author

gobomb commented Mar 16, 2021

github.com/cweill/gotests/gotests

gotests -all -w filepath

自动生成单元测试模板

@gobomb
Copy link
Owner Author

gobomb commented Mar 27, 2021

  1. A deferred function's arguments are evaluated when the defer statement is evaluated. defer函数的参数赋值发生在defer语句赋值之时(发生了复制,所以复制的值取决于defer函数定义的时候的值)
  2. Deferred function calls are executed in Last In First Out order after the surrounding function returns.
  3. Deferred functions may read and assign to the returning function's named return values.(没有发生复制,而是使用了闭包环境的变量)

The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.

https://blog.golang.org/defer-panic-and-recover

@gobomb
Copy link
Owner Author

gobomb commented Mar 28, 2021

An interface value is nil only if the V and T are both unset, (T=nil, V is not set), In particular, a nil interface will always hold a nil type. If we store a nil pointer of type *int inside an interface value, the inner type will be *int regardless of the value of the pointer: (T=*int, V=nil). Such an interface value will therefore be non-nil even when the pointer value V inside is nil.

interface只有type和value同时为nil,才 ==nil

https://golang.org/doc/faq#nil_error

@gobomb
Copy link
Owner Author

gobomb commented Mar 28, 2021

for _, v := range values{} v使用的都是同一个变量

https://golang.org/doc/faq#closures_and_goroutines

@gobomb
Copy link
Owner Author

gobomb commented Apr 6, 2021

Go has no 'reference types'

golang/go@b34f055

@gobomb
Copy link
Owner Author

gobomb commented Apr 6, 2021

  • byte 等同于int8,常用来处理ascii字符
  • rune 等同于int32,常用来处理unicode或utf-8字符
	s := "hi你好"
	fmt.Println(len(s)) //8 = 1+1+3+3
	//golang中的unicode/utf8包提供了用utf-8获取长度的方法
	fmt.Println("RuneCountInString:", utf8.RuneCountInString(s)) //4

	//通过rune类型处理unicode字符
	fmt.Println("rune:", len([]rune(s))) //4

golang中string底层是通过byte数组实现的。中文字符在unicode下占2个字节,在utf-8编码下占3个字节,而golang默认编码正好是utf-8。

@gobomb
Copy link
Owner Author

gobomb commented Apr 7, 2021

On error, any Response can be ignored. A non-nil Response with a non-nil error only occurs when CheckRedirect fails, and even then the returned Response.Body is already closed.

https://golang.org/pkg/net/http/#Client.Do

    resp, err := http.Get("http://xxxx.xxx")
    if err != nil {
        fmt.Println(err)
        return
    }

    defer resp.Body.Close()

这种方式是ok的,不必考虑resp为非nil的情况(出现重定向错误),这种情况下body已经被close

mholt/curl-to-go#6

@gobomb
Copy link
Owner Author

gobomb commented Apr 22, 2021

src/runtime/HACKING.md

The scheduler's job is to match up a G (the code to execute), an M
(where to execute it), and a P (the rights and resources to execute
it).

All g, m, and p objects are heap allocated, but are never freed,
so their memory remains type stable. As a result, the runtime can
avoid write barriers in the depths of the scheduler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant