
获得徽章 0
- 1. 结构体匿名指针的方法可以直接调用
type Engine struct {
*RouteGroup
router *router
groups []*RouteGroup
}
Engine可以直接调用RouteGroup中的方法
2. 中间件的介绍
func A(c *Context) {
part1
c.Next()
part2
}
func B(c *Context) {
part3
c.Next()
part4
}
假设我们应用了中间件 A 和 B,和路由映射的 Handler。c.handlers是这样的[A, B, Handler],c.index初始化为-1。调用c.Next(),接下来的流程是这样的:
c.index++,c.index 变为 0
0 < 3,调用 c.handlers[0],即 A
执行 part1,调用 c.Next()
c.index++,c.index 变为 1
1 < 3,调用 c.handlers[1],即 B
执行 part3,调用 c.Next()
c.index++,c.index 变为 2
2 < 3,调用 c.handlers[2],即Handler
Handler 调用完毕,返回到 B 中的 part4,执行 part4
part4 执行完毕,返回到 A 中的 part2,执行 part2
part2 执行完毕,结束。
一句话说清楚重点,最终的顺序是part1 -> part3 -> Handler -> part 4 -> part2。恰恰满足了我们对中间件的要求,接下来看调用部分的代码,就能全部串起来了。
3. 错误恢复
如果是无法恢复的错误,可以手动触发 panic,当然如果在程序运行过程中出现了类似于数组越界的错误,panic 也会被触发。
panic 会导致程序被中止,但是在退出前,会先处理完当前协程上已经defer 的任务,执行完成后再退出。效果类似于 java 语言的 try...catch。
Go 语言还提供了 recover 函数,可以避免因为 panic 发生而导致整个程序终止,recover 函数只在 defer 中生效。展开评论点赞 - 原始HTTP服务是基于原生库`net/http`搭建的,基础代码如下
```go
http.HandleFunc("/", indexHandler)
http.HandleFunc("/hello", helloHandler)
//
log.Fatal(http.ListenAndServe(":9999", nil))
```
发现`http.ListenAndServe(":9999", nil)`函数的第二个参数是`handle`接口类型,只要实现接口里的函数`ServeHTTP`,就可以自定义函数和静态路由的逻辑实现。
```go
// Engine is the uni handler for all requests
type Engine struct{}
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
switch req.URL.Path {
case "/":
fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path)
case "/hello":
for k, v := range req.Header {
fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
}
default:
fmt.Fprintf(w, "404 NOT FOUND: %s\n", req.URL)
}
}
func main() {
engine := new(Engine)
//拦截了所有的HTTP请求,拥有了统一的控制入口。
log.Fatal(http.ListenAndServe(":9999", engine))
}
```
最后动手实现Gee自定义框架的封装,包括实现函数GET、POST、Run,使得代码风格和gin相似。展开评论点赞 - DAY6
1. 证书鉴权(TLS/SSL)
# 生成私钥
openssl genrsa -out server.key 2048
# 生成证书
openssl req -new -x509 -key server.key -out server.crt -days 3650
# 只读权限
chmod 400 server.key展开评论点赞 - DAY5
1. go编译命令
go build -o protoc-gen-go main.go 目标文件在前,被编译文件在后
2. go mod init Protobuf 初始化项目
protoc --go_out=. ./user.proto 编译proto文件成go语言文件
go mod tidy 拉取欠缺的依赖
3. 一次RPC的完整流程:
客户端(gRPC Sub)调用 A 方法,发起 RPC 调用
对请求信息使用 Protobuf 进行对象序列化压缩(IDL)
服务端(gRPC Server)接收到请求后,解码请求体,进行业务逻辑处理并返回
对响应结果使用 Protobuf 进行对象序列化压缩(IDL)
客户端接受到服务端响应,解码请求体。回调被调用的 A 方法,唤醒正在等待响应(阻塞)的客户端调用并返回响应结果
我们在protobuf协议定义上扩展一个类型定义:Service,这在RPC通讯上有着重要作用。展开1点赞 - DAY4 【Go Protobuf 简明教程】
1. protobuf 即 Protocol Buffers,是一种轻便高效的结构化数据存储格式
2. 安装protobuf编译器 和 下载protobuf的golang支持库,安装protoc-gen-go评论点赞 - DAY3 【Go简明教程、Gin简明教程】【
geektutu.com】
1. 一个文件夹可以作为 package,同一个 package 内部变量、类型、方法等定义可以相互看到。
1) 因为 go run main.go 仅编译 main.go 一个文件,所以命令需要换成 go run main.go calc.go
2. Go 语言也有 Public 和 Private 的概念,粒度是包。如果类型/接口/方法/函数/字段的首字母大写,则是 Public 的,对其他 package 可见,如果首字母小写,则是 Private 的,对其他 package 不可见。
3. 【Gin】Query和Post混合参数 curl "http://localhost:9999/posts?id=9876&page=7" -X POST -d 'username=geektutu&password=1234'
4. 【Gin】Map参数(字典参数)
请求函数 PostFormMap QueryMap
$ curl -g "http://localhost:9999/post?ids[Jack]=001&ids[Tom]=002" -X POST -d 'names[a]=Sam&names[b]=David'
5. 分组路由
v1 := r.Group("/v1")
{
v1.GET("/posts", defaultHandler)
v1.GET("/series", defaultHandler)
}展开评论点赞 - #新人报道# Day1 学习Go语言基础语法并实践
学习要点:
1. := 和 var 的区别
2. 变参函数
1)func add(nums ...int) int{}
2)nums := []int{1, 2, 3, 4}
sum(nums...)
3. 闭包books.studygolang.com intSeq() func() int {
i := 0
return func() int {
i += 1
return i
}
}展开评论点赞