// chainUnaryClientInterceptors chains all unary client interceptors into one.func chainUnaryClientInterceptors(cc *ClientConn) {interceptors := cc.dopts.chainUnaryInts// Prepend dopts.unaryInt to the chaining interceptors if it exists, since unaryInt will// be executed before any other chained interceptors.if cc.dopts.unaryInt != nil {interceptors = append([]UnaryClientInterceptor{cc.dopts.unaryInt}, interceptors...)}var chainedInt UnaryClientInterceptorif len(interceptors) == 0 {chainedInt = nil} else if len(interceptors) == 1 {chainedInt = interceptors[0]} else {chainedInt = func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error {return interceptors[0](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, 0, invoker), opts...)}}cc.dopts.unaryInt = chainedInt}func getChainUnaryInvoker(interceptors []UnaryClientInterceptor, curr int, finalInvoker UnaryInvoker) UnaryInvoker {if curr == len(interceptors)-1 {return finalInvoker}return func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error {return interceptors[curr+1](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, curr+1, finalInvoker), opts...)}}
总结:
通过层层套娃形式,将拦截器数组变成一个链式拦截器,拦截器的next指向他的下一个拦截器。
