gpt4 book ai didi

reflection - golang - 如何访问结构的内部结构(反射?)

转载 作者:数据小太阳 更新时间:2023-10-29 03:15:14 25 4
gpt4 key购买 nike

我需要向 log15 记录器添加属性,但如果我不小心添加了两次,它将出现两次。因此,我想添加逻辑以查看该属性是否已填充,如果已填充则跳过该操作。

这是我输出日志对象时得到的:

log="&{ctx:[field1 val1 field2 val2 field3 val3 field2 val2] h:0xc82052c1e0}"

我如何访问“ctx”字段并在我的值已经存在时进行验证?我已经尝试了一些反射技巧并且可以获取数据类型,但我不知道如何获取值。

最佳答案

我将首先详细了解您的要求,即访问存储在记录器上下文中的属性。

Go 中的反射基于TypeValue。您无权使用 Type 访问任何数据,您只有关于类型的信息(惊喜!)。所以,在这里你必须使用反射的 Value 端。

但是,问题是记录器的ctx 字段没有被导出,所以不能直接访问它。但是,使用一些不安全的操作使其可行。

代码如下:

package main

import (
"fmt"
"reflect"
"unsafe"
)

type logger struct {
ctx []interface{}
}

type Logger interface {
Populate(ctx ...interface{})
}

func NewLogger() Logger {
return &logger{}
}

func (l *logger) Populate(ctx ...interface{}) {
l.ctx = ctx
}

func main() {
log := NewLogger()
log.Populate(42, "42", 84, "84")
fmt.Println(log)
// &{[42 42 84 84]}
v := reflect.ValueOf(log).Elem()
field := v.FieldByName("ctx")
ar := *(*[]interface{})(unsafe.Pointer(field.UnsafeAddr()))

for _, i := range ar {
fmt.Println(i)
}
// 42 42 84 84
}

Go playground

永远不要那样做

该代码有效,并产生您所期望的结果。但是,您所做的是使用反射和不安全操作从第三方 库的未导出 结构中获取值。我的英语不够好,无法正确表达这有多糟糕

如果您不想在记录器中有两次相同的属性,请不要一开始就把它放两次,这比维护上面的代码要好得多,也容易得多。

如果您对此仍然不够信任自己,那么请将记录器包装在一个结构中,您可以在该结构中存储记录器中包含的属性。至少这将是您亲手操作的东西,并且做同样的工作。

因此,您可以自由使用此代码。但是,如果您想帮自己一个忙,在这种情况下就不会使用它。

关于reflection - golang - 如何访问结构的内部结构(反射?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37493805/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com