github.com/gogf/gf/v2@v2.7.4/util/gconv/gconv_int.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gconv
     8  
     9  import (
    10  	"math"
    11  	"reflect"
    12  	"strconv"
    13  
    14  	"github.com/gogf/gf/v2/encoding/gbinary"
    15  	"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
    16  )
    17  
    18  // Int converts `any` to int.
    19  func Int(any interface{}) int {
    20  	if any == nil {
    21  		return 0
    22  	}
    23  	if v, ok := any.(int); ok {
    24  		return v
    25  	}
    26  	return int(Int64(any))
    27  }
    28  
    29  // Int8 converts `any` to int8.
    30  func Int8(any interface{}) int8 {
    31  	if any == nil {
    32  		return 0
    33  	}
    34  	if v, ok := any.(int8); ok {
    35  		return v
    36  	}
    37  	return int8(Int64(any))
    38  }
    39  
    40  // Int16 converts `any` to int16.
    41  func Int16(any interface{}) int16 {
    42  	if any == nil {
    43  		return 0
    44  	}
    45  	if v, ok := any.(int16); ok {
    46  		return v
    47  	}
    48  	return int16(Int64(any))
    49  }
    50  
    51  // Int32 converts `any` to int32.
    52  func Int32(any interface{}) int32 {
    53  	if any == nil {
    54  		return 0
    55  	}
    56  	if v, ok := any.(int32); ok {
    57  		return v
    58  	}
    59  	return int32(Int64(any))
    60  }
    61  
    62  // Int64 converts `any` to int64.
    63  func Int64(any interface{}) int64 {
    64  	if any == nil {
    65  		return 0
    66  	}
    67  	rv := reflect.ValueOf(any)
    68  	switch rv.Kind() {
    69  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    70  		return int64(rv.Int())
    71  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    72  		return int64(rv.Uint())
    73  	case reflect.Uintptr:
    74  		return int64(rv.Uint())
    75  	case reflect.Float32, reflect.Float64:
    76  		return int64(rv.Float())
    77  	case reflect.Bool:
    78  		if rv.Bool() {
    79  			return 1
    80  		}
    81  		return 0
    82  	case reflect.Ptr:
    83  		if rv.IsNil() {
    84  			return 0
    85  		}
    86  		if f, ok := any.(localinterface.IInt64); ok {
    87  			return f.Int64()
    88  		}
    89  		return Int64(rv.Elem().Interface())
    90  	case reflect.Slice:
    91  		// TODO: It might panic here for these types.
    92  		if rv.Type().Elem().Kind() == reflect.Uint8 {
    93  			return gbinary.DecodeToInt64(rv.Bytes())
    94  		}
    95  	case reflect.String:
    96  		var (
    97  			s       = rv.String()
    98  			isMinus = false
    99  		)
   100  		if len(s) > 0 {
   101  			if s[0] == '-' {
   102  				isMinus = true
   103  				s = s[1:]
   104  			} else if s[0] == '+' {
   105  				s = s[1:]
   106  			}
   107  		}
   108  		// Hexadecimal.
   109  		if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
   110  			if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
   111  				if isMinus {
   112  					return -v
   113  				}
   114  				return v
   115  			}
   116  		}
   117  		// Decimal.
   118  		if v, e := strconv.ParseInt(s, 10, 64); e == nil {
   119  			if isMinus {
   120  				return -v
   121  			}
   122  			return v
   123  		}
   124  		// Float64.
   125  		if valueInt64 := Float64(s); math.IsNaN(valueInt64) {
   126  			return 0
   127  		} else {
   128  			return int64(valueInt64)
   129  		}
   130  	default:
   131  		if f, ok := any.(localinterface.IInt64); ok {
   132  			return f.Int64()
   133  		}
   134  	}
   135  	return 0
   136  }