英文:
How to implement GetStringValueByField(n interface{}, field_name string) string
问题
我正在尝试实现一种方法,通过给定的结构体和字段名作为字符串,从任意结构体字段中获取一个值作为字符串。
使用反射(reflect),总是会导致恐慌。
恐慌: reflect: 在接口值上调用 reflect.Value.FieldByName
goroutine 16 [运行中]
// 尝试实现 GetStringValueByFieldName()
package main
import "fmt"
import "reflect"
import "strconv"
func main() {
a := Order{A: "asdf", B: 123}
fmt.Println(a)
fmt.Println(Test1(a, "A"))
fmt.Println(Test1(a, "B"))
}
type Order struct {
A string
B int64
}
func Test1(n interface{}, field_name string) string {
var x string
s := reflect.ValueOf(&n).Elem()
x, ok := s.FieldByName(field_name).Interface().(string)
if ok {
fmt.Println(ok)
}
return x
}
func GetStringValueByFieldName(n interface{}, field_name string) string {
ps := reflect.ValueOf(&n)
// 结构体
s := ps.Elem()
if s.Kind() == reflect.Struct {
f := s.FieldByName(field_name)
if f.IsValid() {
if f.CanSet() {
if f.Kind() == reflect.Int {
return strconv.FormatInt(f.Int(), 10)
}
if f.Kind() == reflect.String {
return f.String()
}
}
}
}
return ""
}
希望这可以帮助到你!
英文:
I am trying to implement a method to get a value from a arbitrary struct-field as a string given by the struct and the fieldname as a string.
With reflect it is always panicing.
> panic: reflect: call of reflect.Value.FieldByName on interface Value
> goroutine 16 [running]
// attempt to implement GetStringValueByFieldName()
package main
import "fmt"
import "reflect"
import "strconv"
func main() {
a:=Order{A:"asdf", B:123}
fmt.Println(a)
fmt.Println(Test1(a, "A"))
fmt.Println(Test1(a, "B"))
}
type Order struct {
A string
B int64
}
func Test1 (n interface{}, field_name string) string {
var x string
s := reflect.ValueOf(&n).Elem()
x, ok := s.FieldByName(field_name).Interface().(string)
if ok {
fmt.Println(ok)
}
return x
}
func GetStringValueByFieldName(n interface{}, field_name string) string {
ps := reflect.ValueOf(&n)
// struct
s := ps.Elem()
if s.Kind() == reflect.Struct {
f := s.FieldByName(field_name)
if f.IsValid() {
if f.CanSet() {
if f.Kind() == reflect.Int {
return strconv.FormatInt(f.Int(),10)
}
if f.Kind() == reflect.String {
return f.String()
}
}
}
}
return ""
}
答案1
得分: 7
这是获取字符串字段的方法:
package main
import (
"fmt"
"reflect"
)
func main() {
a := Order{A: "asdf", B: 123}
fmt.Println(a)
fmt.Println(GetStringValueByFieldName(a, "A"))
fmt.Println(GetStringValueByFieldName(&a, "A"))
fmt.Println(GetStringValueByFieldName(a, "B"))
fmt.Println(GetStringValueByFieldName(0, "B"))
fmt.Println(GetStringValueByFieldName(a, "C"))
}
type Order struct {
A string
B int64
}
func GetStringValueByFieldName(n interface{}, field_name string) (string, bool) {
s := reflect.ValueOf(n)
if s.Kind() == reflect.Ptr {
s = s.Elem()
}
if s.Kind() != reflect.Struct {
return "", false
}
f := s.FieldByName(field_name)
if !f.IsValid() {
return "", false
}
switch f.Kind() {
case reflect.String:
return f.Interface().(string), true
case reflect.Int:
return strconv.FormatInt(f.Int(), 10), true
// add cases for more kinds as needed.
default:
return "", false
// or use fmt.Sprint(f.Interface())
}
}
英文:
Here's how to get a string field by name:
package main
import (
"fmt"
"reflect"
)
func main() {
a := Order{A: "asdf", B: 123}
fmt.Println(a)
fmt.Println(GetStringValueByFieldName(a, "A"))
fmt.Println(GetStringValueByFieldName(&a, "A"))
fmt.Println(GetStringValueByFieldName(a, "B"))
fmt.Println(GetStringValueByFieldName(0, "B"))
fmt.Println(GetStringValueByFieldName(a, "C"))
}
type Order struct {
A string
B int64
}
func GetStringValueByFieldName(n interface{}, field_name string) (string, bool) {
s := reflect.ValueOf(n)
if s.Kind() == reflect.Ptr {
s = s.Elem()
}
if s.Kind() != reflect.Struct {
return "", false
}
f := s.FieldByName(field_name)
if !f.IsValid() {
return "", false
}
switch f.Kind() {
case reflect.String:
return f.Interface().(string), true
case reflect.Int:
return strconv.FormatInt(f.Int(), 10), true
// add cases for more kinds as needed.
default:
return "", false
// or use fmt.Sprint(f.Interface())
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论