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() 添加到数组中?

