如何使用反射初始化结构体字段的值?

huangapple go评论72阅读模式
英文:

How to initialize a struct value fields using reflection?

问题

我有一个.ini配置文件,我想用它来初始化一个Configuration结构体。

我想使用Configuration字段的名称,并循环遍历它们,以便将对应的值从.ini文件中填充到我的新实例中。

我认为实现这个的最佳方式可能是使用反射API(也许我完全错了,告诉我...)

我的问题是我无法弄清楚如何访问字段的名称(如果可能的话)

以下是我的代码:

package test
import(
     "reflect"
     "gopkg.in/ini.v1"
 )

type Config struct {
    certPath string
    keyPath  string
    caPath   string
}

func InitConfig(iniConf *ini.File) *Config{
    config:=new(Config)
    var valuePtr reflect.Value = reflect.ValueOf(config)
    var value reflect.Value = valuePtr.Elem()
    for i := 0; i < value.NumField(); i++ {
        field := value.Field(i)
        if field.Type() == reflect.TypeOf("") {
            //这里是我的问题,我无法获取字段的名称,这个方法不存在... :&#39;(
            value:=cfg.GetSection("section").GetKey(field.GetName())
            field.SetString(value)
        }
    }
    return config
}

希望能帮到你...

英文:

I got a .ini configuration file that I want to use to initialize a Configuration struct.

I'd like to use the Configuration fields names and loop over them to populate my new instance with the corresponding value in the .ini file.

I thought the best way to achieve this might be reflection API (maybe I'm totally wrong, tell me...)

My problem here is that I cannot figure out how to access field's name (if it is at least possible)

Here is my code:

package test
import(
	 &quot;reflect&quot;
	 &quot;gopkg.in/ini.v1&quot;
 )

type Config struct {
	certPath string
	keyPath  string
	caPath   string
}

func InitConfig(iniConf *ini.File) *Config{
	config:=new(Config)
	var valuePtr reflect.Value = reflect.ValueOf(config)
	var value reflect.Value = valuePtr.Elem()
	for i := 0; i &lt; value.NumField(); i++ {
		field := value.Field(i)
		if field.Type() == reflect.TypeOf(&quot;&quot;) {
			//here is my problem, I can&#39;t get the field name, this method does not exist... :&#39;(
			value:=cfg.GetSection(&quot;section&quot;).GetKey(field.GetName())
			field.SetString(value)
		}
	}
	return config
}

Any help appreciated...

答案1

得分: 2

使用type获取StructField。StructField具有name属性:

 name := value.Type().Field(i).Name

请注意,ini包的File.MapToSection.MapTo方法实现了这个功能。

英文:

Use the type to get a StructField. The StructField has the name:

 name := value.Type().Field(i).Name

Note that the ini package's File.MapTo and Section.MapTo methods implement this functionality.

答案2

得分: 1

虽然 @MuffinTop 解决了你的直接问题,但我认为你可能正在解决一个错误的问题。我个人知道至少有两个包,github.com/Thomasdezeeuw/inigopkg.in/gcfg.v1,它们能够解析 INI 格式的文件(具有不同级别的 "INI-ness"),并使用反射自动填充你的结构体类型的值,因此对你来说,只需要正确设置结构体字段的标签(如果需要的话)。

我在生产环境中使用过这两个包,所以可以立即推荐它们给你。你可能还可以在 godoc.org 上找到更多专门用于解析 INI 文件的包。

英文:

While @MuffinTop solved your immediate issue, I'd say you may be solving a wrong problem. I personally know of at least two packages, github.com/Thomasdezeeuw/ini and gopkg.in/gcfg.v1, which are able to parse INI-style files (of the various level of "INI-ness", FWIW) and automatically populate your struct-typed values using reflection, so for you it merely amounts to properly setting tags on the fields of your struct (if needed at all).

I used both of these packages in production so am able to immediately recommend them. You might find more packages dedicated to parsing INI files on godoc.org.

huangapple
  • 本文由 发表于 2016年2月1日 00:03:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/35115906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定