You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
naza/pkg/nazareflect/value.go

119 lines
2.5 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/naza
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package nazareflect
import (
"bytes"
"reflect"
)
func IsNil(actual interface{}) bool {
if actual == nil {
return true
}
v := reflect.ValueOf(actual)
k := v.Kind()
if k == reflect.Chan || k == reflect.Map || k == reflect.Ptr || k == reflect.Interface || k == reflect.Slice {
return v.IsNil()
}
return false
}
// TODO chef: 考虑是否将EqualInteger放入Equal中但是需考虑会给Equal带来额外的性能开销
func Equal(expected, actual interface{}) bool {
if expected == nil {
return IsNil(actual)
}
exp, ok := expected.([]byte)
if ok {
act, ok := actual.([]byte)
if !ok {
return false
}
return bytes.Equal(exp, act)
}
return reflect.DeepEqual(expected, actual)
}
// 用于判断不同类型的整型的值是否相等比如int8(1)和int32(1)做比较结果为true
// 注意如果a或b不是整型则直接返回false
func EqualInteger(a, b interface{}) bool {
// a有3种状态有符号整型无符号整型非整型
// b同理也是3种状态
// 那么总共有3*3种组合需要判断
aiv, aiok := tryInt(a)
biv, biok := tryInt(b)
if aiok && biok { // a,b都是有符号整型 (1)
return aiv == biv
}
auv, auok := tryUint(a)
buv, buok := tryUint(b)
if auok && buok { // a,b都是无符号整型 (1)
return auv == buv
}
if aiok && buok { // a是有符号整型b是无符号整型 (1)
if aiv < 0 {
return false
}
return uint64(aiv) == buv
}
if auok && biok { // a是无符号整型b是有符号整型 (1)
if biv < 0 {
return false
}
return uint64(biv) == auv
}
// 剩下的情况,至少有一个不是整型 (5)
return false
}
func tryInt(actual interface{}) (int64, bool) {
v := reflect.ValueOf(actual)
k := v.Kind()
switch k {
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
return v.Int(), true
}
return 0, false
}
func tryUint(actual interface{}) (uint64, bool) {
v := reflect.ValueOf(actual)
k := v.Kind()
switch k {
case reflect.Uint:
fallthrough
case reflect.Uint8:
fallthrough
case reflect.Uint16:
fallthrough
case reflect.Uint32:
fallthrough
case reflect.Uint64:
fallthrough
case reflect.Uintptr:
return v.Uint(), true
}
return 0, false
}