如何使用反射在Go语言中创建一个接口值类型的对象

3

更新

我想要创建一个辅助函数,用于测试读取环境变量的功能。它使用了envconfig

func Test_T2(t *testing.T) {

    os.Setenv("APP_PARAM_STR", "string value")
    os.Setenv("APP_PARAM_INT", "12")

    os.Setenv("APP_PARAM_DURATION", "15s")
    os.Setenv("APP_PARAM_INT", "44")

    c := ConfigTwo{}

    d := ConfigTwo{
        ParamDuration: 15*time.Second,
        ParamInt:      44,
    }

    helper(t, &c, &d)
}

func helper(t *testing.T, confObject, expValue interface{}) {
    t.Helper()

    err := getParams(&confObject)
    if !assert.NoError(t, err) {
        return
    }

    assert.Equal(t, expValue, confObject)
}

func getParams(cfg interface{}) error {
    return envconfig.Process("APP", cfg)

}

** UPDATE 2 **
It works. Thanks everyone.

如果只有getPrams函数,它是有效的。但是如果我添加助手函数(我需要测试不同的结构体),我会遇到一个错误:specification must be a struct pointer

envconfig 在这里执行两个检查 (链接)


2
这个检查用来检查s是否是一个指向结构体的指针,所以无论你的helperFunc做了什么,如果它不返回一个指向结构体的指针,那么你将无法使其工作。顺便问一下,你的问题是什么?你是在问如何使用反射创建一个指向结构体的指针吗?还是在问如何使用反射复制任意值?这是两个非常不同的事情。 - undefined
是的,如何创建一个指针,这就是我的问题。 - undefined
reflect.New 返回给定类型的指针。就像内置函数 new 一样,当你在 Go 中执行 new(string) 时,你会得到一个类型为 *string 的值,即给定类型的指针。https://play.golang.org/p/cmtvfJrLG1r - undefined
reflect.New返回reflect.Value。 paramType := reflect.PtrTo(reflect.TypeOf(param)) cpy := reflect.New(paramType).Interface() err := envconfig.Process(defaultAppPrefix, cpy)这会导致错误规范必须是结构指针,因为reflect.ValueOf(cpy).Elem().Kind()是Ptr而不是Struct。 - undefined
2
编辑问题以显示helperFunc的调用方式(包括参数类型)和预期的返回类型和值。也许reflect.PtrTo的调用是不必要的,但如果没有看到函数的使用方式,我们无法确定。 - user12258482
我没有更新。请看一下。 - undefined
1个回答

2
使用这段代码。参数是指向预期值的指针。
func helper(t *testing.T, pexpected interface{}) {
    t.Helper()
    pactual := reflect.New(reflect.TypeOf(pexpected).Elem()).Interface()

    err := getParams(pactual)
    if !assert.NoError(t, err) {
        return
    }

    assert.Equal(t, pexpected, pactual)
}

代码表达式 reflect.New(reflect.TypeOf(pexeceted).Elem()).Interface() 返回一个指向新空值的指针,该空值与 pexpected 指向的类型相同。

可以这样调用:

helper(t, &ConfigTwo{A: "expected A Field", B: "expected B field"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接