Golang中如何将多个结构体字段传递到通道

Golang中如何将多个结构体字段传递到通道 我有一个类似这样的结构体

type collector struct {
TopActiveID1     				   *prometheus.Desc
TopActiveID2     				   *prometheus.Desc
TopActiveID3     				   *prometheus.Desc
TopActiveID4     				   *prometheus.Desc
TopActiveID5     				   *prometheus.Desc
TopActiveID6     				   *prometheus.Desc
TopActiveID7     				   *prometheus.Desc
TopActiveID8     				   *prometheus.Desc
TopActiveID9     				   *prometheus.Desc
TopActiveID10    				   *prometheus.Desc
}

我需要将每个字段传递给一个通道。有没有办法一次性完成,而不需要像下面这样逐个操作?

func (collector *collector) Describe(ch chan<- *prometheus.Desc) {
ch <- collector.TopActiveID1
ch <- collector.TopActiveID2
ch <- collector.TopActiveID3
ch <- collector.TopActiveID4
ch <- collector.TopActiveID5
ch <- collector.TopActiveID6
ch <- collector.TopActiveID7
ch <- collector.TopActiveID8
ch <- collector.TopActiveID9
ch <- collector.TopActiveID10
}

更多关于Golang中如何将多个结构体字段传递到通道的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

太棒了!

非常感谢您的所有帮助!学到了很多

更多关于Golang中如何将多个结构体字段传递到通道的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


如果将字段定义为包含10个值的数组,您能否对它们进行迭代。

问题:有没有办法在循环中添加这些 prometheus.NewDesc?

太棒了!!!

非常感谢您的帮助。我会尝试自己解决剩下的问题,但如果再次遇到困难,我会回来请教。

大致如下:

func newCollector() *collector {
  return &collector{
    TopActive: []*prometheus.Desc{
      prometheus.NewDesc("topactiveid_1", "Shows top active item number 1", nil, nil),
      prometheus.NewDesc("topactiveid_2", "Shows top active item number 2", nil, nil),
      prometheus.NewDesc("topactiveid_3", "Shows top active item number 3", nil, nil),
      // 以此类推
    }
  }
}

如果你能轻松构造调用中传入的字符串,应该可以通过类似这样的方式实现:

func newCollector() *collector {
  n := 10
  descs := make([]*prometheus.Desc, n)

  for i := 1; i <= n; i++ {
    descs[i-1] = prometheus.NewDesc(
      fmt.Sprintf("topactiveid_%v", i),
      fmt.Sprintf("Shows top active item number %v", i),
      nil,
      nil,
    )
  }

  return &collector{ TopAcitve: descs }
}

可以使用反射来一次性发送所有字段到通道,这样可以避免逐个手动操作。以下是实现方法:

import (
    "reflect"
    "github.com/prometheus/client_golang/prometheus"
)

func (collector *collector) Describe(ch chan<- *prometheus.Desc) {
    v := reflect.ValueOf(collector).Elem()
    t := v.Type()
    
    for i := 0; i < v.NumField(); i++ {
        field := v.Field(i)
        if field.Type() == reflect.TypeOf((*prometheus.Desc)(nil)) {
            if desc, ok := field.Interface().(*prometheus.Desc); ok && desc != nil {
                ch <- desc
            }
        }
    }
}

或者,如果你想要更简洁的版本,可以创建一个字段切片然后遍历:

func (collector *collector) Describe(ch chan<- *prometheus.Desc) {
    fields := []*prometheus.Desc{
        collector.TopActiveID1,
        collector.TopActiveID2,
        collector.TopActiveID3,
        collector.TopActiveID4,
        collector.TopActiveID5,
        collector.TopActiveID6,
        collector.TopActiveID7,
        collector.TopActiveID8,
        collector.TopActiveID9,
        collector.TopActiveID10,
    }
    
    for _, field := range fields {
        if field != nil {
            ch <- field
        }
    }
}

反射方法更加通用,可以自动处理结构体中的所有*prometheus.Desc类型字段,而切片方法虽然需要显式列出所有字段,但代码更直观且类型安全。

好的,我继续做了这个

type collector struct{
TopActive     []*prometheus.Desc
}

在将其发送到通道之前,我需要实际使用它,这一点我本应在最初的帖子中包含,但我还在做这个

func newCollector() *collector {
return &collector{
TopActiveID1:                       prometheus.NewDesc("topactiveid_1", "Shows top active item number 1", nil, nil),
TopActiveID2:                       prometheus.NewDesc("topactiveid_2", "Shows top active item number 2", nil, nil),
TopActiveID3:                       prometheus.NewDesc("topactiveid_3", "Shows top active item number 3", nil, nil),
TopActiveID4:                       prometheus.NewDesc("topactiveid_4", "Shows top active item number 4", nil, nil),
TopActiveID5:                       prometheus.NewDesc("topactiveid_5", "Shows top active item number 5", nil, nil),
TopActiveID6:                       prometheus.NewDesc("topactiveid_6", "Shows top active item number 6", nil, nil),
TopActiveID7:                       prometheus.NewDesc("topactiveid_7", "Shows top active item number 7", nil, nil),
TopActiveID8:                       prometheus.NewDesc("topactiveid_8", "Shows top active item number 8", nil, nil),
TopActiveID9:                       prometheus.NewDesc("topactiveid_9", "Shows top active item number 9", nil, nil),
TopActiveID10:                      prometheus.NewDesc("topactiveid_10", "Shows top active item number 10", nil, nil),
}
}

我应该如何将所有 prometheus.NewDesc() 添加到数组中?

回到顶部