Skip to content

Repository files navigation

reflectutils

reflectutils is for setting your struct value by using string name and path that follows reflectutils rules.

The rules

  • .Name to set a property by field name
  • .Person.Name to set the name of the current property
  • .Person.Addresses[0].Phone to set an element of an array property
  • .Person.Addresses[].Name it will create a object of address and set it's property
  • .Person.MapData.Name it can also set value to map

How to install

gogetgithub.com/sunfmin/reflectutils

By given these structs

typePersonstruct {
NamestringScorefloat64GenderintCompany*CompanyDepartments []*DepartmentProjects []ProjectPhonesmap[string]stringLanguagesmap[string]Language
}
typeLanguagestruct {
CodestringNamestring
}
typeCompanystruct {
NamestringPhone*PhonePhone2**Phone
}
typeDepartmentstruct {
IdintNamestring
}
typeProjectstruct {
IdstringNamestringMembers []*Person
}
typePhonestruct {
Numberstring
}

For How to set simple field

varp*PersonSet(&p, "Name", "Felix")
Set(&p, "Score", 66.88)
Set(&p, "Gender", 1)
printJsonV(p)
fmt.Println(MustGet(&p, "Score"))
//Output:// {// "Name": "Felix",// "Score": 66.88,// "Gender": 1,// "Company": null,// "Departments": null,// "Projects": null,// "Phones": null,// "Languages": null// }// 66.88

For how to set a struct property

p:=&Person{}
Set(p, ".Company.Name", "The Plant")
Set(p, ".Company.Phone.Number", "911")
printJsonV(p)
fmt.Println(MustGet(&p, ".Company.Phone.Number"))
//Output:// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": {// "Name": "The Plant",// "Phone": {// "Number": "911"// }// },// "Departments": null,// "Projects": null,// "Phones": null,// "Languages": null// }// 911

For how to set slice and it's property

varp*PersonSet(&p, "Departments[0].Id", 1)
Set(&p, "Departments[0].Name", "High Tech")
Set(&p, "Projects[0].Name", "UIBuilder")
// if you jump the index for an array, It will put nil in between// So there will be no index out of range error.Set(&p, "Departments[3].Id", 1)
Set(&p, "Departments[3].Name", "High Tech")
printJsonV(p)
fmt.Println(MustGet(&p, "Departments[3].Name"))
fmt.Println(MustGet(&p, "Departments[4].Name"))
fmt.Println(MustGet(&p, "Projects[0].Name"))
//Output:// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": null,// "Departments": [// {// "Id": 1,// "Name": "High Tech"// },// null,// null,// {// "Id": 1,// "Name": "High Tech"// }// ],// "Projects": [// {// "Id": "",// "Name": "UIBuilder",// "Members": null// }// ],// "Phones": null,// "Languages": null// }// High Tech// <nil>// UIBuilder

For how to set map property

varp*PersonSet(&p, "Languages.en_US.Name", "United States")
Set(&p, "Languages.en_US.Code", "en_US")
Set(&p, "Languages.zh_CN.Name", "China")
Set(&p, "Languages.zh_CN.Code", "zh_CN")
printJsonV(p)
fmt.Println(MustGet(&p, "Languages.zh_CN.Code"))
//Output:// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": null,// "Departments": null,// "Projects": null,// "Phones": null,// "Languages": {// "en_US": {// "Code": "en_US",// "Name": "United States"// },// "zh_CN": {// "Code": "zh_CN",// "Name": "China"// }// }// }// zh_CN

You can do whatever deeper you like

varp*PersonSet(&p, "Projects[0].Members[0].Company.Phone.Number", "911")
printJsonV(p)
fmt.Println(MustGet(&p, "Projects[0].Members[0].Company.Phone.Number"))
//Output:// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": null,// "Departments": null,// "Projects": [// {// "Id": "",// "Name": "",// "Members": [// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": {// "Name": "",// "Phone": {// "Number": "911"// }// },// "Departments": null,// "Projects": null,// "Phones": null,// "Languages": null// }// ]// }// ],// "Phones": null,// "Languages": null// }// 911

A new way to append to an array

varp*Personfori:=1; i<6; i++ {
vard*DepartmentSet(&d, "Id", i)
Set(&d, "Name", fmt.Sprintf("Department of Energy %d", i))
Set(&p, "Departments[]", d)
}
printJsonV(p)
//Output:// {// "Name": "",// "Score": 0,// "Gender": 0,// "Company": null,// "Departments": [// {// "Id": 1,// "Name": "Department of Energy 1"// },// {// "Id": 2,// "Name": "Department of Energy 2"// },// {// "Id": 3,// "Name": "Department of Energy 3"// },// {// "Id": 4,// "Name": "Department of Energy 4"// },// {// "Id": 5,// "Name": "Department of Energy 5"// }// ],// "Projects": null,// "Phones": null,// "Languages": null// }

You could also set []byte data to string property, and vice versa. And set string value to int, float

typeObjstruct {
ByteProperty []byteStringPropertystringIntValueintFloatValuefloat64IntValueForBytesint
}
varo*ObjSet(&o, "ByteProperty", "hello")
Set(&o, "StringProperty", []byte{0x46, 0x65, 0x6c, 0x69, 0x78})
Set(&o, "IntValue", "22")
Set(&o, "IntValueForBytes", []byte{0x32, 0x32})
Set(&o, "FloatValue", "22.88")
fmt.Println(string(o.ByteProperty))
fmt.Println(o.StringProperty)
fmt.Println(o.IntValue)
fmt.Println(o.FloatValue)
fmt.Println(o.IntValueForBytes)
//Output://hello//Felix//22//22.88//22

If you set a property that don't exists, it gives you an error.

varp*Personerr:=Set(&p, "Whatever.Not.Exists", "911")
fmt.Println(err)
//Output:// no such field.

Get Type of a deep nested object

typeVariantstruct {
Namestring
}
typeProductstruct {
Variants []*VariantByCodemap[string]*Variant
}
typeObjstruct {
MainProduct*Product
}
varo*Objfmt.Println(GetType(o, "MainProduct.Variants[0].Name"))
fmt.Println(GetType(o, "MainProduct.Variants[0]"))
fmt.Println(GetType(o, "MainProduct.Variants"))
fmt.Println(GetType(o, "MainProduct"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc"))
fmt.Println(GetType(o, "MainProduct.ByCode"))
fmt.Println(GetType(o, "x123.ByCode"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc.NotExist"))
//Output://string//*reflectutils_test.Variant//[]*reflectutils_test.Variant//*reflectutils_test.Product//*reflectutils_test.Variant//map[string]*reflectutils_test.Variant//<nil>//<nil>

About

Easier way to use reflect to set and get values in Go

Resources

Stars

14 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages