Skip to content

Instantly share code, notes, and snippets.

@cuevasclemente
Last active February 26, 2016 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cuevasclemente/c0a88f6b56e138b43a17 to your computer and use it in GitHub Desktop.
Save cuevasclemente/c0a88f6b56e138b43a17 to your computer and use it in GitHub Desktop.
Functions that show Go reflection to write some abstracted code
package abstractreflection
import "reflect"
// Sum adds all the fields of `struct1` to `struct2`
// This will only work if the two structs are of the same
// type, and have flat properties
// that are all float64. If not, the result will be `nil`
func Sum(struct1 interface{}, struct2 interface{}) interface{} {
t := reflect.TypeOf(struct1)
if t != reflect.TypeOf(struct2) {
return nil
}
toReturn := reflect.Indirect(reflect.New(t))
v1 := reflect.ValueOf(struct1)
v2 := reflect.ValueOf(struct2)
numField := t.NumField()
for i := 0; i < numField; i++ {
f1V := v1.Field(i)
if f1V.Kind().String() != "float64" {
continue
}
f1 := f1V.Float()
f2 := v2.Field(i).Float()
toReturn.Field(i).Set(reflect.ValueOf(f1 + f2))
}
return toReturn.Interface()
}
// Scale scales all of the float64 fields in
// structToScale by scaleFactor (i.e: multiplies them
// by scaleFactor). Scale returns `nil` if
// structToScale's kind is not "struct"
func Scale(structToScale interface{}, scaleFactor float64) interface{} {
t := reflect.TypeOf(structToScale)
if t.Kind().String() != "struct" {
return nil
}
toReturn := reflect.Indirect(reflect.New(t))
v := reflect.ValueOf(structToScale)
fieldNum := t.NumField()
for i := 0; i < fieldNum; i++ {
fValue := v.Field(i)
if fValue.Kind().String() != "float64" {
continue
}
toReturn.Field(i).Set(reflect.ValueOf(fValue.Float() * scaleFactor))
}
return toReturn.Interface()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment