请教大家这段代码是什么用法

今天看到一段代码,在for循环里面定义了一个func(下面代码第9行),这个属于什么用法?作用是什么?这个func有没有执行?

func (g *Group) Eval(ctx context.Context, ts time.Time) {
    for i, rule := range g.rules {
        select {
        case <-g.done:
            return
        default:
        }

        func(i int, rule Rule) {
            sp, ctx := opentracing.StartSpanFromContext(ctx, "rule")
            sp.SetTag("name", rule.Name())
            defer func(t time.Time) {
                sp.Finish()
                evalDuration.Observe(time.Since(t).Seconds())
                rule.SetEvaluationTime(time.Since(t))
            }(time.Now())

            evalTotal.Inc()

            vector, err := rule.Eval(ctx, ts, g.opts.QueryFunc, g.opts.ExternalURL)
            if err != nil {
                // Canceled queries are intentional termination of queries. This normally
                // happens on shutdown and thus we skip logging of any errors here.
                if _, ok := err.(promql.ErrQueryCanceled); !ok {
                    level.Warn(g.logger).Log("msg", "Evaluating rule failed", "rule", rule, "err", err)
                }
                evalFailures.Inc()
                return
            }

            if ar, ok := rule.(*AlertingRule); ok {
                g.opts.NotifyFunc(ctx, ar.vector.String(), ar.currentAlerts()...)
            }
            var (
                numOutOfOrder = 0
                numDuplicates = 0
            )

            app, err := g.opts.Appendable.Appender()
            if err != nil {
                level.Warn(g.logger).Log("msg", "creating appender failed", "err", err)
                return
            }

            seriesReturned := make(map[string]labels.Labels, len(g.seriesInPreviousEval[i]))
            for _, s := range vector {
                if _, err := app.Add(s.Metric, s.T, s.V); err != nil {
                    switch err {
                    case storage.ErrOutOfOrderSample:
                        numOutOfOrder++
                        level.Debug(g.logger).Log("msg", "Rule evaluation result discarded", "err", err, "sample", s)
                    case storage.ErrDuplicateSampleForTimestamp:
                        numDuplicates++
                        level.Debug(g.logger).Log("msg", "Rule evaluation result discarded", "err", err, "sample", s)
                    default:
                        level.Warn(g.logger).Log("msg", "Rule evaluation result discarded", "err", err, "sample", s)
                    }
                } else {
                    seriesReturned[s.Metric.String()] = s.Metric
                }
            }
            if numOutOfOrder > 0 {
                level.Warn(g.logger).Log("msg", "Error on ingesting out-of-order result from rule evaluation", "numDropped", numOutOfOrder)
            }
            if numDuplicates > 0 {
                level.Warn(g.logger).Log("msg", "Error on ingesting results from rule evaluation with different value but same timestamp", "numDropped", numDuplicates)
            }

            for metric, lset := range g.seriesInPreviousEval[i] {
                if _, ok := seriesReturned[metric]; !ok {
                    // Series no longer exposed, mark it stale.
                    _, err = app.Add(lset, timestamp.FromTime(ts), math.Float64frombits(value.StaleNaN))
                    switch err {
                    case nil:
                    case storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp:
                        // Do not count these in logging, as this is expected if series
                        // is exposed from a different rule.
                    default:
                        level.Warn(g.logger).Log("msg", "adding stale sample failed", "sample", metric, "err", err)
                    }
                }
            }
            if err := app.Commit(); err != nil {
                level.Warn(g.logger).Log("msg", "rule sample appending failed", "err", err)
            } else {
                g.seriesInPreviousEval[i] = seriesReturned
            }
        }(i, rule)
    }
}
已邀请:

sheepbao - https://sheepbao.github.io 爱go,爱编程,领域网络开发,流媒体、分布式、网络加速

赞同来自: wuhan marks_gui

这个属于什么用法?

匿名函数

作用是什么?

跟普通函数没啥区别,就是没有名字而已

这个func有没有执行?

有, }(i, rule),倒数第三行,表示传参和执行

更多的用法比如


func main() {
  printHello:=func() {
     println("hello")
  }

  printHello()
}

lrita

赞同来自: wuhan

  • 这个属于什么用法? -> 匿名函数
  • 作用是什么?因为go没有cpp的RAII,同时defer的执行时机是基于函数的,而不是基于作用域的。因此要用匿名函数封装的方式,实现在循环中执行defer.
  • 这个func有没有执行?当然有执行

要回复问题请先登录注册