分类 Golang 中的文章

kratos 源码解析 TODO

如果是一个简单的需求,那么我们用 Go http、gin、beego 足以 再复杂点呢,接口多起来了,我们寻求团队分工合作,功能解藕,所以按功能、层级将服务进行拆分,服务间使用 http、grpc 进行调用 当服务多起来了,我们需要一个规范统一各个服务的代码,这里的代码是项目层级、中间件调用、日……

阅读全文

Golang Interface

结论 interface 本质上也是一种类型,所以在判断它是否为 nil 时, 如果是其它类型转成的 interface,其实中间已经包含了结构体信息,所以这时它已经不是 nil 了 背景 此文是由一个 bug 引发的思考,代码如下 业务代码 代码经过精简,请暂时忽略注释的的内容 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……

阅读全文

gin 源码探究

官方的 http 包 我们从流量打入端口开始,gin 其实是官方 http 包的封装 1 2 3 4 5 6 7 8 9 // 这里是 gin.Run 的逻辑 func (engine *Engine) Run(addr ...string) (err error) { defer func() { debugPrintError(err) }() address := resolveAddress(addr) debugPrint("Listening and serving HTTP on %s\n", address) err = http.ListenAndServe(address, engine) return } 再回顾下官方 http 包的使用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 func HelloServer(w http.ResponseWriter, req *http.Request) { io.WriteString(w, "hello, world!\n") } func run() { // 点进去就发现,它使用 DefaultServeMux 注册了路由地址 http.HandleFunc("/hello", HelloServer) // 这里……

阅读全文

Debug in container

有时候我们需要对容器内部进程进行debug,当然我们可以直接拷贝delve到容器进行命令行调试, 但是由于缺少源文件会导致无法看见调试的上下文代码,可以配置 ~/.config/dlv/config.yml 中的 substitute-path参数,不过这样就繁琐了。 在容器启动时就使用delve启动debug 1. 下载delve并以容器……

阅读全文

Go 包多版本管理

项目格式 -project -bytes_core -go.mod -pool -a.go -b.go -redis_core -etcd_core 关于不同core包,版本管理的问题,主要有以下几点需要注意 每个core包里需要有mod文件,mod文件开头需要以域名/当前包路径,例如github.com/xxx/project/bytes_core 在修改完某一个core包代码后,commit完后,单独打……

阅读全文

golang unsafe初探——根据字段计算结构体实例地址

在Go中,第一个字段的地址即为结构体地址 观察代码运行结果,理解golang对象与字段地址的偏移计算 说明:Pointer和uintptr方法可以理解为本质上都是指针,前者一般用来转化类型,后者用来计算地址 type Buffer struct { buf [1500]byte n int8 } func main() { instance := new(Buffer) { println(instance) println(instance.buf[:]) println(&instance.buf[0]) b := (*Buffer)(unsafe.Pointer(&instance.buf[0])) // 根据buf字段算出实例对象的地址……

阅读全文

Golang 正则

. 匹配多行,匹配包括 re := regexp.MustCompile(`(?s)i(.*?)u`) fmt.Println(re.MatchString("i\nlove\nu")) // true // 部分使用 s 模式,下同 re := regexp.MustCompile(`i(?s:.*?)l(.*)`) // 只有第一个括号中使用了s模式 fmt.Println(re.FindString("i \nlove\n u")) // i\nlove 忽略大小写 re := regexp.MustCompile(`(?i)love`) fmt.Println(re.MatchString("i\nLOVE\nu")) // true 多行使用^ $匹配行首和行尾 re := regexp.MustCompile(`(?m)^love$`) fmt.Println(re.MatchString("i\nlove\nu")) // true……

阅读全文