本文整理汇总了Golang中go/constant.Compare函数的典型用法代码示例。如果您正苦于以下问题:Golang Compare函数的具体用法?Golang Compare怎么用?Golang Compare使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Compare函数的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: equalObj
// equalObj reports how x and y differ. They are assumed to belong to
// different universes so cannot be compared directly.
func equalObj(x, y types.Object) error {
if reflect.TypeOf(x) != reflect.TypeOf(y) {
return fmt.Errorf("%T vs %T", x, y)
}
xt := x.Type()
yt := y.Type()
switch x.(type) {
case *types.Var, *types.Func:
// ok
case *types.Const:
xval := x.(*types.Const).Val()
yval := y.(*types.Const).Val()
// Use string comparison for floating-point values since rounding is permitted.
if constant.Compare(xval, token.NEQ, yval) &&
!(xval.Kind() == constant.Float && xval.String() == yval.String()) {
return fmt.Errorf("unequal constants %s vs %s", xval, yval)
}
case *types.TypeName:
xt = xt.Underlying()
yt = yt.Underlying()
default:
return fmt.Errorf("unexpected %T", x)
}
return equalType(xt, yt)
}
示例2: VisitPost
func (constantFolderVisitor) VisitPost(expr Expr) (retExpr Expr) {
defer func() {
// go/constant operations can panic for a number of reasons (like division
// by zero), but it's difficult to preemptively detect when they will. It's
// safest to just recover here without folding the expression and let
// normalization or evaluation deal with error handling.
if r := recover(); r != nil {
retExpr = expr
}
}()
switch t := expr.(type) {
case *ParenExpr:
if cv, ok := t.Expr.(*NumVal); ok {
return cv
}
case *UnaryExpr:
if cv, ok := t.Expr.(*NumVal); ok {
if token, ok := unaryOpToToken[t.Operator]; ok {
return &NumVal{Value: constant.UnaryOp(token, cv.Value, 0)}
}
if token, ok := unaryOpToTokenIntOnly[t.Operator]; ok {
if intVal, ok := cv.asConstantInt(); ok {
return &NumVal{Value: constant.UnaryOp(token, intVal, 0)}
}
}
}
case *BinaryExpr:
l, okL := t.Left.(*NumVal)
r, okR := t.Right.(*NumVal)
if okL && okR {
if token, ok := binaryOpToToken[t.Operator]; ok {
return &NumVal{Value: constant.BinaryOp(l.Value, token, r.Value)}
}
if token, ok := binaryOpToTokenIntOnly[t.Operator]; ok {
if lInt, ok := l.asConstantInt(); ok {
if rInt, ok := r.asConstantInt(); ok {
return &NumVal{Value: constant.BinaryOp(lInt, token, rInt)}
}
}
}
if token, ok := binaryShiftOpToToken[t.Operator]; ok {
if lInt, ok := l.asConstantInt(); ok {
if rInt64, err := r.asInt64(); err == nil && rInt64 >= 0 {
return &NumVal{Value: constant.Shift(lInt, token, uint(rInt64))}
}
}
}
}
case *ComparisonExpr:
l, okL := t.Left.(*NumVal)
r, okR := t.Right.(*NumVal)
if okL && okR {
if token, ok := comparisonOpToToken[t.Operator]; ok {
return MakeDBool(DBool(constant.Compare(l.Value, token, r.Value)))
}
}
}
return expr
}
示例3: constantCompare
func constantCompare(op token.Token, x, y constant.Value) (r bool, err error) {
defer func() {
if ierr := recover(); ierr != nil {
err = fmt.Errorf("%v", ierr)
}
}()
r = constant.Compare(x, op, y)
return
}
示例4: comparison
func (check *Checker) comparison(x, y *operand, op token.Token) {
// spec: "In any comparison, the first operand must be assignable
// to the type of the second operand, or vice versa."
err := ""
if x.assignableTo(check.conf, y.typ, nil) || y.assignableTo(check.conf, x.typ, nil) {
defined := false
switch op {
case token.EQL, token.NEQ:
// spec: "The equality operators == and != apply to operands that are comparable."
defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
case token.LSS, token.LEQ, token.GTR, token.GEQ:
// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
defined = isOrdered(x.typ)
default:
unreachable()
}
if !defined {
typ := x.typ
if x.isNil() {
typ = y.typ
}
err = check.sprintf("operator %s not defined for %s", op, typ)
}
} else {
err = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
}
if err != "" {
check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
x.mode = invalid
return
}
if x.mode == constant_ && y.mode == constant_ {
x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
// The operands are never materialized; no need to update
// their types.
} else {
x.mode = value
// The operands have now their final types, which at run-
// time will be materialized. Update the expression trees.
// If the current types are untyped, the materialized type
// is the respective default type.
check.updateExprType(x.expr, defaultType(x.typ), true)
check.updateExprType(y.expr, defaultType(y.typ), true)
}
// spec: "Comparison operators compare two operands and yield
// an untyped boolean value."
x.typ = Typ[UntypedBool]
}
示例5: checkConstValue
func checkConstValue(t *testing.T, prog *ssa.Program, obj *types.Const) {
c := prog.ConstValue(obj)
// fmt.Printf("ConstValue(%s) = %s\n", obj, c) // debugging
if c == nil {
t.Errorf("ConstValue(%s) == nil", obj)
return
}
if !types.Identical(c.Type(), obj.Type()) {
t.Errorf("ConstValue(%s).Type() == %s", obj, c.Type())
return
}
if obj.Name() != "nil" {
if !exact.Compare(c.Value, token.EQL, obj.Val()) {
t.Errorf("ConstValue(%s).Value (%s) != %s",
obj, c.Value, obj.Val())
return
}
}
}
示例6: compare
func compare(a, b interface{}, tok token.Token) bool {
vala := reflect.ValueOf(a)
valb := reflect.ValueOf(b)
ak := vala.Kind()
bk := valb.Kind()
switch {
case ak >= reflect.Int && ak <= reflect.Int64:
if bk >= reflect.Int && bk <= reflect.Int64 {
return constant.Compare(constant.MakeInt64(vala.Int()), tok, constant.MakeInt64(valb.Int()))
}
if bk == reflect.Float32 || bk == reflect.Float64 {
return constant.Compare(constant.MakeFloat64(float64(vala.Int())), tok, constant.MakeFloat64(valb.Float()))
}
if bk == reflect.String {
bla, err := strconv.ParseFloat(valb.String(), 64)
if err != nil {
return false
}
return constant.Compare(constant.MakeFloat64(float64(vala.Int())), tok, constant.MakeFloat64(bla))
}
case ak == reflect.Float32 || ak == reflect.Float64:
if bk == reflect.Float32 || bk == reflect.Float64 {
return constant.Compare(constant.MakeFloat64(vala.Float()), tok, constant.MakeFloat64(valb.Float()))
}
if bk >= reflect.Int && bk <= reflect.Int64 {
return constant.Compare(constant.MakeFloat64(vala.Float()), tok, constant.MakeFloat64(float64(valb.Int())))
}
if bk == reflect.String {
bla, err := strconv.ParseFloat(valb.String(), 64)
if err != nil {
return false
}
return constant.Compare(constant.MakeFloat64(vala.Float()), tok, constant.MakeFloat64(bla))
}
case ak == reflect.String:
if bk == reflect.String {
return constant.Compare(constant.MakeString(vala.String()), tok, constant.MakeString(valb.String()))
}
}
if reflect.TypeOf(a).String() == "time.Time" && reflect.TypeOf(b).String() == "time.Time" {
var x, y int64
x = 1
if vala.MethodByName("Equal").Call([]reflect.Value{valb})[0].Bool() {
y = 1
} else if vala.MethodByName("Before").Call([]reflect.Value{valb})[0].Bool() {
y = 2
}
return constant.Compare(constant.MakeInt64(x), tok, constant.MakeInt64(y))
}
if tok == token.EQL {
return reflect.DeepEqual(a, b)
}
return false
}
示例7: matchExpr
// matchExpr reports whether pattern x matches y.
//
// If tr.allowWildcards, Idents in x that refer to parameters are
// treated as wildcards, and match any y that is assignable to the
// parameter type; matchExpr records this correspondence in tr.env.
// Otherwise, matchExpr simply reports whether the two trees are
// equivalent.
//
// A wildcard appearing more than once in the pattern must
// consistently match the same tree.
//
func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
if x == nil && y == nil {
return true
}
if x == nil || y == nil {
return false
}
x = unparen(x)
y = unparen(y)
// Is x a wildcard? (a reference to a 'before' parameter)
if xobj, ok := tr.wildcardObj(x); ok {
return tr.matchWildcard(xobj, y)
}
// Object identifiers (including pkg-qualified ones)
// are handled semantically, not syntactically.
xobj := isRef(x, tr.info)
yobj := isRef(y, tr.info)
if xobj != nil {
return xobj == yobj
}
if yobj != nil {
return false
}
// TODO(adonovan): audit: we cannot assume these ast.Exprs
// contain non-nil pointers. e.g. ImportSpec.Name may be a
// nil *ast.Ident.
if reflect.TypeOf(x) != reflect.TypeOf(y) {
return false
}
switch x := x.(type) {
case *ast.Ident:
log.Fatalf("unexpected Ident: %s", astString(tr.fset, x))
case *ast.BasicLit:
y := y.(*ast.BasicLit)
xval := exact.MakeFromLiteral(x.Value, x.Kind, 0)
yval := exact.MakeFromLiteral(y.Value, y.Kind, 0)
return exact.Compare(xval, token.EQL, yval)
case *ast.FuncLit:
// func literals (and thus statement syntax) never match.
return false
case *ast.CompositeLit:
y := y.(*ast.CompositeLit)
return (x.Type == nil) == (y.Type == nil) &&
(x.Type == nil || tr.matchType(x.Type, y.Type)) &&
tr.matchExprs(x.Elts, y.Elts)
case *ast.SelectorExpr:
y := y.(*ast.SelectorExpr)
return tr.matchSelectorExpr(x, y) &&
tr.info.Selections[x].Obj() == tr.info.Selections[y].Obj()
case *ast.IndexExpr:
y := y.(*ast.IndexExpr)
return tr.matchExpr(x.X, y.X) &&
tr.matchExpr(x.Index, y.Index)
case *ast.SliceExpr:
y := y.(*ast.SliceExpr)
return tr.matchExpr(x.X, y.X) &&
tr.matchExpr(x.Low, y.Low) &&
tr.matchExpr(x.High, y.High) &&
tr.matchExpr(x.Max, y.Max) &&
x.Slice3 == y.Slice3
case *ast.TypeAssertExpr:
y := y.(*ast.TypeAssertExpr)
return tr.matchExpr(x.X, y.X) &&
tr.matchType(x.Type, y.Type)
case *ast.CallExpr:
y := y.(*ast.CallExpr)
match := tr.matchExpr // function call
if tr.info.Types[x.Fun].IsType() {
match = tr.matchType // type conversion
}
return x.Ellipsis.IsValid() == y.Ellipsis.IsValid() &&
match(x.Fun, y.Fun) &&
tr.matchExprs(x.Args, y.Args)
case *ast.StarExpr:
y := y.(*ast.StarExpr)
return tr.matchExpr(x.X, y.X)
//.........这里部分代码省略.........
示例8: VisitPost
func (constantFolderVisitor) VisitPost(expr Expr) (retExpr Expr) {
defer func() {
// go/constant operations can panic for a number of reasons (like division
// by zero), but it's difficult to preemptively detect when they will. It's
// safest to just recover here without folding the expression and let
// normalization or evaluation deal with error handling.
if r := recover(); r != nil {
retExpr = expr
}
}()
switch t := expr.(type) {
case *ParenExpr:
switch cv := t.Expr.(type) {
case *NumVal, *StrVal:
return cv
}
case *UnaryExpr:
switch cv := t.Expr.(type) {
case *NumVal:
if token, ok := unaryOpToToken[t.Operator]; ok {
return &NumVal{Value: constant.UnaryOp(token, cv.Value, 0)}
}
if token, ok := unaryOpToTokenIntOnly[t.Operator]; ok {
if intVal, ok := cv.asConstantInt(); ok {
return &NumVal{Value: constant.UnaryOp(token, intVal, 0)}
}
}
}
case *BinaryExpr:
switch l := t.Left.(type) {
case *NumVal:
if r, ok := t.Right.(*NumVal); ok {
if token, ok := binaryOpToToken[t.Operator]; ok {
return &NumVal{Value: constant.BinaryOp(l.Value, token, r.Value)}
}
if token, ok := binaryOpToTokenIntOnly[t.Operator]; ok {
if lInt, ok := l.asConstantInt(); ok {
if rInt, ok := r.asConstantInt(); ok {
return &NumVal{Value: constant.BinaryOp(lInt, token, rInt)}
}
}
}
if token, ok := binaryShiftOpToToken[t.Operator]; ok {
if lInt, ok := l.asConstantInt(); ok {
if rInt64, err := r.asInt64(); err == nil && rInt64 >= 0 {
return &NumVal{Value: constant.Shift(lInt, token, uint(rInt64))}
}
}
}
}
case *StrVal:
if r, ok := t.Right.(*StrVal); ok {
switch t.Operator {
case Concat:
// When folding string-like constants, if either was byte-escaped,
// the result is also considered byte escaped.
return &StrVal{s: l.s + r.s, bytesEsc: l.bytesEsc || r.bytesEsc}
}
}
}
case *ComparisonExpr:
switch l := t.Left.(type) {
case *NumVal:
if r, ok := t.Right.(*NumVal); ok {
if token, ok := comparisonOpToToken[t.Operator]; ok {
return MakeDBool(DBool(constant.Compare(l.Value, token, r.Value)))
}
}
case *StrVal:
// ComparisonExpr folding for String-like constants is not significantly different
// from constant evalutation during normalization (because both should be exact,
// unlike numeric comparisons). Still, folding these comparisons when possible here
// can reduce the amount of work performed during type checking, can reduce necessary
// allocations, and maintains symmetry with numeric constants.
if r, ok := t.Right.(*StrVal); ok {
switch t.Operator {
case EQ:
return MakeDBool(DBool(l.s == r.s))
case NE:
return MakeDBool(DBool(l.s != r.s))
case LT:
return MakeDBool(DBool(l.s < r.s))
case LE:
return MakeDBool(DBool(l.s <= r.s))
case GT:
return MakeDBool(DBool(l.s > r.s))
case GE:
return MakeDBool(DBool(l.s >= r.s))
}
}
}
}
return expr
}