如何动态获取结构体中的字段

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

How to get field in a struct dynamically

问题

我有以下结构体。我有一个名为csv的方法,它将使用逗号分隔的值将字段连接成一个字符串。

package main

import (
    "bytes"
    "strconv"
)

type Event struct {
    B_id    string
    B_nam   string
    B_typ   int
    B_uuid  string
    B_mj_id int
    B_mi_id int
    B_uid   string
    B_url   string
    B_mac   string
    E_typ   string
    E_time  string
    C_id    string
    D_os    string
    D_os_v  string
    D_nam   string
    D_v     string
    Br_nam  string
    Br_v    string
    A_pkg   string
    A_id    string
    M_u_id  string
    bn_id   string
}

func (e *Event) Csv() string {
    var buffer bytes.Buffer
    var comma string = ","

    buffer.WriteString(e.B_id)
    buffer.WriteString(comma)
    buffer.WriteString(e.B_nam)
    buffer.WriteString(comma)
    buffer.WriteString(strconv.Itoa(e.B_typ))
    buffer.WriteString(comma)
    buffer.WriteString(e.B_uuid)
    buffer.WriteString(comma)
    buffer.WriteString(strconv.Itoa(e.B_mj_id))
    buffer.WriteString(comma)
    buffer.WriteString(strconv.Itoa(e.B_mi_id))
    buffer.WriteString(comma)
    buffer.WriteString(e.B_uid)
    buffer.WriteString(comma)
    buffer.WriteString(e.B_url)
    buffer.WriteString(comma)
    buffer.WriteString(e.B_mac)
    buffer.WriteString(comma)
    buffer.WriteString(e.E_typ)
    buffer.WriteString(comma)
    buffer.WriteString(e.E_time)
    buffer.WriteString(comma)
    buffer.WriteString(e.C_id)
    buffer.WriteString(comma)
    buffer.WriteString(e.D_os)
    buffer.WriteString(comma)
    buffer.WriteString(e.D_os_v)
    buffer.WriteString(comma)
    buffer.WriteString(e.D_nam)
    buffer.WriteString(comma)
    buffer.WriteString(e.D_v)
    buffer.WriteString(comma)
    buffer.WriteString(e.Br_nam)
    buffer.WriteString(comma)
    buffer.WriteString(e.Br_v)
    buffer.WriteString(comma)
    buffer.WriteString(e.A_pkg)
    buffer.WriteString(comma)
    buffer.WriteString(e.A_id)
    buffer.WriteString(comma)
    buffer.WriteString(e.M_u_id)
    buffer.WriteString(comma)
    buffer.WriteString(e.bn_id)

    return buffer.String()
}

在这里,我将每个字段添加到缓冲区中,并将其作为字符串返回。这段代码看起来不太好。

是否可能动态获取字段值?类似于以下方式:

func (e *Event) Csv() string {
    var buffer bytes.Buffer
    var comma string = ","

    var fieldValues [22]string = // 以某种方式获取字段值
    for i := 0; i < 22; i++ {
        buffer.WriteString(fieldValues[i])
        buffer.WriteString(comma)
    }

    return buffer.String()
}
英文:

I have the below struct. I have the method csv which will return concatenate the fields in a string with comma separated value.

package main
import (
&quot;bytes&quot;
&quot;strconv&quot;
)
type Event struct {
B_id string
B_nam string
B_typ int
B_uuid string
B_mj_id int
B_mi_id int
B_uid string
B_url string
B_mac string
E_typ string
E_time string
C_id string
D_os string
D_os_v string
D_nam string
D_v string
Br_nam string
Br_v string
A_pkg string
A_id string
M_u_id string
bn_id string
}
func (e *Event) Csv() string {
var buffer bytes.Buffer
var comma string = &quot;,&quot;
buffer.WriteString(e.B_id)
buffer.WriteString(comma)
buffer.WriteString(e.B_nam)
buffer.WriteString(comma)
buffer.WriteString(strconv.Itoa(e.B_typ))
buffer.WriteString(comma)
buffer.WriteString(e.B_uuid)
buffer.WriteString(comma)
buffer.WriteString(strconv.Itoa(e.B_mj_id))
buffer.WriteString(comma)
buffer.WriteString(strconv.Itoa(e.B_mi_id))
buffer.WriteString(comma)
buffer.WriteString(e.B_uid)
buffer.WriteString(comma)
buffer.WriteString(e.B_url)
buffer.WriteString(comma)
buffer.WriteString(e.B_mac)
buffer.WriteString(comma)
buffer.WriteString(e.E_typ)
buffer.WriteString(comma)
buffer.WriteString(e.E_time)
buffer.WriteString(comma)
buffer.WriteString(e.C_id)
buffer.WriteString(comma)
buffer.WriteString(e.D_os)
buffer.WriteString(comma)
buffer.WriteString(e.D_os_v)
buffer.WriteString(comma)
buffer.WriteString(e.D_nam)
buffer.WriteString(comma)
buffer.WriteString(e.D_v)
buffer.WriteString(comma)
buffer.WriteString(e.Br_nam)
buffer.WriteString(comma)
buffer.WriteString(e.Br_v)
buffer.WriteString(comma)
buffer.WriteString(e.A_pkg)
buffer.WriteString(comma)
buffer.WriteString(e.A_id)
buffer.WriteString(comma)
buffer.WriteString(e.M_u_id)
buffer.WriteString(comma)
buffer.WriteString(e.bn_id)
return buffer.String()
}

Here you can see that I adding each fields in a buffer and returning it as a string. This code does not looks nice.

Is it possible to get the field value dynamically? Something like,

func (e *Event) Csv() string {
var buffer bytes.Buffer
var comma string = &quot;,&quot;
var x [22]string fieldValues = //Somehow get the field Values
for i := 0; i &lt; 22; i++ {
buffer.WriteString(B_id)
buffer.WriteString(comma)
}
return buffer.String()
}

答案1

得分: 3

使用reflect来迭代结构体字段。

以下是示例代码:

package main

import (
	"fmt"
	"reflect"
	"strings"
)

type Event struct {
	B_id    string
	B_nam   string
	B_typ   string
	B_uuid  string
	B_mj_id string
	B_mi_id string
	B_uid   string
	B_url   string
	B_mac   string
	E_typ   string
	E_time  string
	C_id    string
	D_os    string
	D_os_v  string
	D_nam   string
	D_v     string
	Br_nam  string
	Br_v    string
	A_pkg   string
	A_id    string
	M_u_id  string
	// bn_id   string  //FIXME: unexported fields not work for reflection?
}

func main() {
	// 初始化结构体,这里只取了几个字段作为示例。
	e := Event{A_id: "hah", M_u_id: "dadas"}
	v := reflect.ValueOf(e)

	values := make([]string, v.NumField())
	for i := 0; i < v.NumField(); i++ {
		values[i] = v.Field(i).String()
	}

	fmt.Println(strings.Join(values, ","))
}

希望对你有帮助。

你可以在这里在线运行它:http://play.golang.org/p/ZheOnMFRnI

英文:

Use reflect to iterate the struct fields.

Here is the example:

package main
import (
&quot;fmt&quot;
&quot;reflect&quot;
&quot;strings&quot;
)
type Event struct {
B_id    string
B_nam   string
B_typ   string
B_uuid  string
B_mj_id string
B_mi_id string
B_uid   string
B_url   string
B_mac   string
E_typ   string
E_time  string
C_id    string
D_os    string
D_os_v  string
D_nam   string
D_v     string
Br_nam  string
Br_v    string
A_pkg   string
A_id    string
M_u_id  string
// bn_id   string  //FIXME: unexported fields not work for reflection?
}
func main() {
// initialize your struct, I only take a few of fields as example.
e := Event{A_id: &quot;hah&quot;, M_u_id: &quot;dadas&quot;}
v := reflect.ValueOf(e)
values := make([]string, v.NumField())
for i := 0; i &lt; v.NumField(); i++ {
values[i] = v.Field(i).String()
}
fmt.Println(strings.Join(values, &quot;,&quot;))
}

May this be helpful.

You can run it online: http://play.golang.org/p/ZheOnMFRnI

huangapple
  • 本文由 发表于 2015年11月25日 21:06:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/33917278.html
匿名

发表评论

匿名网友

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

确定