go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/less.go (about) 1 package fu 2 3 import ( 4 "reflect" 5 ) 6 7 /* 8 Less compares two values and returns true if the left value is less than right one otherwise it returns false 9 */ 10 func Less(a, b reflect.Value) bool { 11 if a.Kind() != b.Kind() { 12 panic("values must have the same type") 13 } 14 if m := a.MethodByName("Less"); m.IsValid() { 15 t := m.Type() 16 if t.NumOut() == 1 && t.NumIn() == 1 && t.Out(0).Kind() == reflect.Bool && t.In(0) == a.Type() { 17 return m.Call([]reflect.Value{b})[0].Bool() 18 } 19 } 20 switch a.Kind() { 21 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 22 return a.Int() < b.Int() 23 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 24 return a.Uint() < b.Uint() 25 case reflect.Float32, reflect.Float64: 26 return a.Float() < b.Float() 27 case reflect.String: 28 return a.String() < b.String() 29 case reflect.Ptr, reflect.Interface: 30 if a.IsNil() && !b.IsNil() { 31 return true 32 } else if b.IsNil() { 33 return false 34 } 35 return Less(a.Elem(), b.Elem()) 36 case reflect.Struct: 37 N := a.NumField() 38 for i := 0; i < N; i++ { 39 if Less(a.Field(i), b.Field(i)) { 40 return true 41 } else if Less(b.Field(i), a.Field(i)) { 42 return false 43 } 44 } 45 return false 46 case reflect.Array: 47 if a.Len() != b.Len() { 48 panic("values must have the same type") 49 } 50 N := a.Len() 51 for i := 0; i < N; i++ { 52 if Less(a.Index(i), b.Index(i)) { 53 return true 54 } else if Less(b.Index(i), a.Index(i)) { 55 return false 56 } 57 } 58 return false 59 default: 60 panic("only int,float,string,struct,array are allowed to compare") 61 } 62 }