检查一个切片中是否包含具有给定字段值的结构体。

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

Check if a slice contains a struct with a given field value

问题

尝试检查某个切片中的结构体是否包含给定字段的值,所以我写了这个代码。

func main() {
    //测试
    Objs := []Obj{{1,"xxx"},{2,"yyy"},{3,"zzz"}}
    res := containsStructFieldValue(Objs,"X",1)
    fmt.Println(res)
}


type Obj struct {
    X int
    Y string
}

func containsStructFieldValue(slice []Obj ,fieldName string,fieldValueToCheck interface {}) bool{
    for _,s := range slice{
        r := reflect.ValueOf(s)
        f := r.FieldByName(fieldName)
        if f.IsValid(){
            if f.Interface() == fieldValueToCheck{
                return true //存在具有给定值的字段
            }
        }
    }
    return false
}

我希望它适用于任何给定的结构体类型,但当我尝试将参数设置为slice []interface{}时,发现这是不可能的。有没有办法使上述方法适用于任何结构体类型?

英文:

Trying to check if a struct in some slice contains a value of a given field so i wrote this

   func main() {
    //test
	Objs := []Obj{{1,"xxx"},{2,"yyy"},{3,"zzz"}}
	res := containsStructFieldValue(Objs,"X",1)
	fmt.Println(res)
}


type Obj struct {
	X int
	Y string
}

func containsStructFieldValue(slice []Obj ,fieldName string,fieldValueToCheck interface {}) bool{
	for _,s := range slice{
		r := reflect.ValueOf(s)
		f := r.FieldByName(fieldName)
		if f.IsValid(){
			if f.Interface() == fieldValueToCheck{
				return true //a field with the given value exists
			}
		}
	}
	return false
}

i need it to work for any given struct type but when i tried slice []interface as the parameter i found out that its not possible, any idea on how to make the above method work for any struct type?

答案1

得分: 7

你可以使用reflect来遍历interface{},例如:

func containsStructFieldValue(slice interface{}, fieldName string, fieldValueToCheck interface{}) bool {
    rangeOnMe := reflect.ValueOf(slice)

    for i := 0; i < rangeOnMe.Len(); i++ {
        s := rangeOnMe.Index(i)
        f := s.FieldByName(fieldName)
        if f.IsValid() {
            if f.Interface() == fieldValueToCheck {
                return true
            }
        }
    }

    return false
}

请注意,我没有检查slice是否确实是一个切片...如果不是,这段代码会引发恐慌。如果你想避免这种行为,你可以使用reflect.Kind来进行检查。

英文:

You can use reflect to range over an interface{}, for instance:

func containsStructFieldValue(slice interface{} ,fieldName string,fieldValueToCheck interface {}) bool{

    rangeOnMe := reflect.ValueOf(slice)

    for i := 0; i &lt; rangeOnMe.Len(); i++ {
        s := rangeOnMe.Index(i)
        f := s.FieldByName(fieldName)
        if f.IsValid(){
            if f.Interface() == fieldValueToCheck {
                return true
            }
        }
    }
}

Note that I did not check that slice is indeed a slice... If not, this code will panic. You can use reflect.Kind to check this if you want to avoid this behaviour.

huangapple
  • 本文由 发表于 2014年7月15日 23:07:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/24761724.html
匿名

发表评论

匿名网友

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

确定