登录
首页 >  Golang >  Go问答

使用reflect在go中将struct的每个字段设置为非nil值

来源:stackoverflow

时间:2024-02-25 21:54:25 102浏览 收藏

一分耕耘,一分收获!既然都打开这篇《使用reflect在go中将struct的每个字段设置为非nil值》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新Golang相关的内容,希望对大家都有所帮助!

问题内容

假设我有某种类型,并且我想实例化该类型的变量,并且每个值都非零。

type event struct {
    happenedatms   int64 
    receivedatms   int64
    fielda         *fieldatype
    fieldb         []*fieldbtype

这是我目前正在尝试的:

eventFields := reflect.TypeOf(Event{})

    event := Event{}
    for i := 0; i < eventFields.NumField(); i++ {
        nonEmptyType := reflect.New(eventFields.Field(i).Type).Elem()
        reflect.ValueOf(&event).Elem().Field(i).Set(nonEmptyType)
    }

但是,运行此代码后,事件变量中的所有字段仍设置为 nil。我怎样才能实现我想要的?


解决方案


reflect 包需要一个指向该结构的指针才能设置其字段。还需要导出这些字段,您可以使用 canset 方法进行检查。

要使用 reflect 初始化指针类型,您只需执行 reflect.new(t.elem()) 即可。要将 mapslicefuncchan 类型初始化为非零,您可以使用 makemapmakeslicemakefunczqbendc zqb 和 makechan 分别具有函数功能。要将接口类型初始化为非零,您可以使用 reflect.structof 创建一个匿名结构类型,并使用目标接口类型的单个嵌入字段,通过嵌入接口类型,结构类型会自动满足接口及其实例可用于将该字段设置为非零。

event := Event{}

rv := reflect.ValueOf(&event).Elem()
for i := 0; i < rv.NumField(); i++ {
    if f := rv.Field(i); isNilable(f) && f.IsNil() && f.CanSet() {
        switch f.Kind() {
        case reflect.Ptr:
            f.Set(reflect.New(f.Type().Elem()))
        case reflect.Slice:
            f.Set(reflect.MakeSlice(f.Type(), 0, 0))
        case reflect.Interface:
            sf := reflect.StructField{
                Name:      f.Type().Name(),
                Type:      f.Type(),
                Anonymous: true,
            }
            rt := reflect.StructOf([]reflect.StructField{sf})
            f.Set(reflect.New(rt).Elem())
            // TODO handle the rest of nilable types
        }
    }
}

https://play.golang.com/p/nQqvUIROqF-

到这里,我们也就讲完了《使用reflect在go中将struct的每个字段设置为非nil值》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>