我正在学习 golang 源代码并陷入延迟函数执行顺序。我有两个文件:一个定义端点的行为,另一个用于测试。我删除了一些与我的问题无关的代码以减少阅读的行数。端点定义文件
// Endpoint is the fundamental building block of servers and clients.
// It represents a single RPC method.
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
// Middleware is a chainable behavior modifier for endpoints.
type Middleware func(Endpoint) Endpoint
// Chain is a helper function for composing middlewares. Requests will
// traverse them in the order they're declared. That is, the first middleware
// is treated as the outermost middleware.
func Chain(outer Middleware, others ...Middleware) Middleware {
return func(next Endpoint) Endpoint {
for i := len(others) - 1; i >= 0; i-- { // reverse
next = others[i](next)
}
return outer(next)
}
}
测试文件包含打印的步骤。
func ExampleChain() {
e := endpoint.Chain(
annotate("first"),
annotate("second"),
annotate("third"),
)(myEndpoint)
if _, err := e(ctx, req); err != nil {
panic(err)
}
// Output:
// first pre
// second pre
// third pre
// my endpoint!
// third post
// second post
// first post
}
var (
ctx = context.Background()
req = struct{}{}
)
据我了解,这三个annotate方法应该先执行,然后endpoint.Chain方法,myEndpoint最后执行。此外,由于pre首先打印,并且当函数返回“post”时,应该按照defergo doc 中的说明进行操作: A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.
所以我期望看到的是
// Output:
// first pre
// first post
// second pre
// second post
// third pre
// third post
// my endpoint!
简而言之,我的问题是:
为什么first pre后面不跟first post,一样second third。
s的顺序post颠倒了。endpoint.Chain反向执行返回值列表但annotate首先annotate评估方法对吗?不是说,pres 被打印,这意味着首先执行内部函数
小怪兽爱吃肉
阿晨1998
相关分类