can someone attach the improved and efficient code? On Friday, March 30, 2012 at 5:29:52 PM UTC+5:30, Luke Mauldin wrote: > > I have the the task of comparing two structs (of the same type) for > equality and returning the field level differences. One of the > restrictions is that I only have to support the types int, bool, float, > string, and time.Time. I have built the following reflection routine and > it works correctly for int, float, bool and string but I cannot figure out > how do the comparison for time.Time because I am getting the compiler error > "type time.Time is not an expression". Does anyone have any suggestions? > Also, looking at the overall code, is there a better or more efficient way > I can solve this problem? > > type CompareResult struct { > FieldName string > Value1 string > Value2 string > } > > func Compare (struct1 interface{}, struct2 interface{}) ([]*CompareResult, > error) { > if struct1 == nil || struct2 == nil { > return nil, errors.New("One of the inputs cannot be nil.") > } > structVal1 := reflect.ValueOf(struct1) > structVal2 := reflect.ValueOf(struct2) > structType := reflect.TypeOf(struct1) > if !(structVal1.Kind() == reflect.Struct && structVal2.Kind() == > reflect.Struct) { > return nil, errors.New("Types must both be structs.") > } > if structVal1.Type() != structVal2.Type() { > return nil, errors.New("Structs must be the same type.") > } > //if structVal1.IsNil() || structVal2.IsNil() { > // return nil, errors.New("Structs cannot be nil.") > //} > numFields := structVal1.NumField() > results := make([]*CompareResult, 0, numFields) > for i := 0; i < numFields; i++ { > //Get values of the structure's fields > val1 := structVal1.Field(i) > val2 := structVal2.Field(i) > //If the values are pointers, get the value of the pointers > isPtr := val1.Kind() == reflect.Ptr > isVal1Nil := false > isVal2Nil := false > if isPtr { > isVal1Nil = val1.IsNil() > isVal2Nil = val2.IsNil() > val1 = val1.Elem() > val2 = val2.Elem() > } > //If the type is a pointer and both values are nil, continue the loop > if isPtr && isVal1Nil && isVal2Nil { > continue; > } > switch val1.Kind() { > case reflect.Int: > int1 := val1.Int() > int2 := val2.Int() > if int1 != int2 { > result := &CompareResult{structType.Field(i).Name, strconv.FormatInt(int1, > 10), strconv.FormatInt(int2, 10) } > results = append(results, result) > } > break; > case reflect.Bool: > bool1 := val1.Bool() > bool2 := val2.Bool() > if bool1 != bool2 { > result := &CompareResult{structType.Field(i).Name, > strconv.FormatBool(bool1), strconv.FormatBool(bool2) } > results = append(results, result) > } > break; > case reflect.Float32, reflect.Float64: > float1 := val1.Float() > float2 := val2.Float() > if float1 != float2 { > result := &CompareResult{structType.Field(i).Name, > strconv.FormatFloat(float1, 'f', 2, 64), strconv.FormatFloat(float2, 'f', > 2, 64) } > results = append(results, result) > } > case reflect.Struct: > //Handle time.Time > timeType := reflect.TypeOf(time.Time) //This gives me a "type time.Time > is not an expression" > if val1.Type() == timeType { > } > break; > case reflect.String: > str1 := val1.String() > str2 := val2.String() > if str1 != str2 { > result := &CompareResult{structType.Field(i).Name, str1, str2 } > results = append(results, result) > } > break; > default: > return nil, errors.New(fmt.Sprintf("Unsupported kind: %v", val1.Kind())) > } > } > return results, nil > } >
-- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.