代码拉取完成,页面将自动刷新
package cast
import (
"errors"
"fmt"
"reflect"
"strconv"
"strings"
"time"
"unsafe"
)
type RawBytes []byte
var errNilPtr = errors.New("destination pointer is nil")
func ConvertAssign(dest, src interface{}) error {
// Common cases, without reflect.
switch s := src.(type) {
case time.Time:
switch d := dest.(type) {
case *string:
if d == nil {
return errNilPtr
}
*d = s.String()
return nil
case *time.Time:
if d == nil {
return errNilPtr
}
*d = s
return nil
}
return nil
case string:
switch d := dest.(type) {
case *string:
if d == nil {
return errNilPtr
}
*d = s
return nil
case *[]byte:
if d == nil {
return errNilPtr
}
*d = []byte(s)
return nil
case *time.Time:
if d == nil {
return errNilPtr
}
*d, _ = time.Parse(GetSysTimeLayout(), s)
return nil
}
case []byte:
switch d := dest.(type) {
case *string:
if d == nil {
return errNilPtr
}
*d = string(s)
return nil
case *interface{}:
if d == nil {
return errNilPtr
}
*d = cloneBytes(s)
return nil
case *[]byte:
if d == nil {
return errNilPtr
}
*d = cloneBytes(s)
return nil
case *RawBytes:
if d == nil {
return errNilPtr
}
*d = s
return nil
case *time.Time:
if d == nil {
return errNilPtr
}
*d, _ = time.Parse(GetSysTimeLayout(), string(s))
return nil
}
case nil:
switch d := dest.(type) {
case *interface{}:
if d == nil {
return errNilPtr
}
*d = nil
return nil
case *[]byte:
if d == nil {
return errNilPtr
}
*d = nil
return nil
case *RawBytes:
if d == nil {
return errNilPtr
}
*d = nil
return nil
}
}
var sv reflect.Value
switch d := dest.(type) {
case *string:
sv = reflect.ValueOf(src)
switch sv.Kind() {
case reflect.Bool:
*d = fmt.Sprintf("%+v", src)
return nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
*d = fmt.Sprintf("%d", src)
return nil
case reflect.Float32, reflect.Float64:
f32, ok := src.(float32)
if ok {
*d = FloatToStr(float64(f32))
} else {
f64, ok := src.(float64)
if ok {
*d = FloatToStr(f64)
}
}
return nil
}
case *[]byte:
sv = reflect.ValueOf(src)
switch sv.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
*d = []byte(fmt.Sprintf("%v", src))
return nil
}
case *RawBytes:
sv = reflect.ValueOf(src)
switch sv.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
*d = RawBytes(fmt.Sprintf("%v", src))
return nil
}
case *bool:
tmpStr := ""
err := ConvertAssign(&tmpStr, src)
if err == nil {
if tmpStr == "false" || tmpStr == "" || tmpStr == "0" {
*d = false
} else {
*d = true
}
}
return err
case *interface{}:
*d = src
return nil
}
/*
if scanner, ok := dest.(sql.Scanner); ok {
return scanner.Scan(src)
}
*/
dpv := reflect.ValueOf(dest)
if dpv.Kind() != reflect.Ptr {
return errors.New("destination not a pointer")
}
if dpv.IsNil() {
return errNilPtr
}
if !sv.IsValid() {
sv = reflect.ValueOf(src)
}
dv := reflect.Indirect(dpv)
if dv.Kind() == sv.Kind() {
dv.Set(sv)
return nil
}
switch dv.Kind() {
case reflect.Ptr:
if src == nil {
dv.Set(reflect.Zero(dv.Type()))
return nil
} else {
dv.Set(reflect.New(dv.Type().Elem()))
return ConvertAssign(dv.Interface(), src)
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
f64, ok := src.(float64)
if ok {
dv.SetInt(int64(f64))
return nil
}
f32, ok := src.(float32)
if ok {
dv.SetInt(int64(f32))
return nil
}
s := asString(src)
base := 10
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
base = 16
s = s[2:]
}
i64, err := strconv.ParseInt(s, base, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
dv.SetInt(i64)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
f64, ok := src.(float64)
if ok {
dv.SetUint(uint64(f64))
return nil
}
f32, ok := src.(float32)
if ok {
dv.SetUint(uint64(f32))
return nil
}
s := asString(src)
base := 10
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
base = 16
s = s[2:]
}
u64, err := strconv.ParseUint(s, base, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
dv.SetUint(u64)
return nil
case reflect.Float32, reflect.Float64:
s := asString(src)
f64, err := strconv.ParseFloat(s, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
dv.SetFloat(f64)
return nil
}
return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
}
func cloneBytes(b []byte) []byte {
if b == nil {
return nil
} else {
c := make([]byte, len(b))
copy(c, b)
return c
}
}
func asString(src interface{}) string {
switch v := src.(type) {
case string:
return v
case []byte:
return string(v)
}
return fmt.Sprintf("%v", src)
}
func GetSysTimeLayout() string {
t := time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC)
strLayout := strings.Replace(t.String(), "+0000 UTC", "", -1)
return strings.TrimSpace(strLayout)
}
func FloatToStr(f float64, precise ...int) string {
formatStr := "%0.8f"
if len(precise) > 0 {
formatStr = fmt.Sprintf("%%0.%df", precise[0])
}
tmpStr := fmt.Sprintf(formatStr, f)
dotIndex := strings.Index(tmpStr, ".")
index := 0
strLen := len(tmpStr)
if dotIndex > 0 && strLen > 0 {
for i := strLen - 1; i >= 0; i-- {
if tmpStr[i] != '0' {
index = i
break
}
}
}
if dotIndex == index {
tmpStr = tmpStr[:index]
} else if index+1 < strLen {
tmpStr = tmpStr[:index+1]
}
return tmpStr
}
func ToString(v interface{}, defaultValue ...string) (string, error) {
var err error
var retStr string
var ok bool
retStr, ok = v.(string)
if ok {
return retStr, nil
}
err = ConvertAssign(&retStr, v)
if err != nil && len(defaultValue) > 0 {
retStr = defaultValue[0]
}
return retStr, err
}
func ToStringValue(v interface{}, defaultValue ...string) string {
ret, _ := ToString(v, defaultValue...)
return ret
}
func FormatFloat32(f float32, precise ...int) string {
return FormatFloat(float64(f), precise...)
}
func FormatFloat(f float64, precise ...int) string {
formatStr := "%0.8f"
if len(precise) > 0 {
formatStr = fmt.Sprintf("%%0.%df", precise[0])
}
tmpStr := fmt.Sprintf(formatStr, f)
dotIndex := strings.Index(tmpStr, ".")
index := 0
strLen := len(tmpStr)
if dotIndex > 0 && strLen > 0 {
for i := strLen - 1; i >= 0; i-- {
if tmpStr[i] != '0' {
index = i
break
}
}
}
if dotIndex == index {
tmpStr = tmpStr[:index]
} else if index+1 < strLen {
tmpStr = tmpStr[:index+1]
}
return tmpStr
}
func ToBool(v interface{}, defaultValue ...bool) (bool, error) {
var err error
var ret bool
var ok bool
ret, ok = v.(bool)
if ok {
return ret, nil
}
err = ConvertAssign(&ret, v)
if err != nil && len(defaultValue) > 0 {
ret = defaultValue[0]
}
return ret, err
}
func ToBoolValue(v interface{}, defaultValue ...bool) bool {
ret, _ := ToBool(v, defaultValue...)
return ret
}
func ToInt64(v interface{}, defaultValue ...int64) (int64, error) {
var err error
var ret int64
var ok bool
ret, ok = v.(int64)
if ok {
return ret, nil
}
err = ConvertAssign(&ret, v)
if err != nil && len(defaultValue) > 0 {
ret = defaultValue[0]
}
return ret, err
}
func ToInt64Value(v interface{}, defaultValue ...int64) int64 {
ret, _ := ToInt64(v, defaultValue...)
return ret
}
func ToInt(v interface{}, defaultValue ...int) (int, error) {
var err error
var ret int
var ok bool
ret, ok = v.(int)
if ok {
return ret, nil
}
err = ConvertAssign(&ret, v)
if err != nil && len(defaultValue) > 0 {
ret = defaultValue[0]
}
return ret, err
}
func ToIntValue(v interface{}, defaultValue ...int) int {
ret, _ := ToInt(v, defaultValue...)
return ret
}
func ToFloat32(v interface{}, defaultValue ...float32) (float32, error) {
var err error
var ret float32
var ok bool
ret, ok = v.(float32)
if ok {
return ret, nil
}
err = ConvertAssign(&ret, v)
if err != nil && len(defaultValue) > 0 {
ret = defaultValue[0]
}
return ret, err
}
func ToFloat64(v interface{}, defaultValue ...float64) (float64, error) {
var err error
var ret float64
var ok bool
ret, ok = v.(float64)
if ok {
return ret, nil
}
err = ConvertAssign(&ret, v)
if err != nil && len(defaultValue) > 0 {
ret = defaultValue[0]
}
return ret, err
}
func ToFloat64Value(v interface{}, defaultValue ...float64) float64 {
ret, _ := ToFloat64(v, defaultValue...)
return ret
}
func ToFloat32Value(v interface{}, defaultValue ...float32) float32 {
ret, _ := ToFloat32(v, defaultValue...)
return ret
}
func ToMapStringInterface(v interface{}) (map[string]interface{}, bool) {
m, ok := v.(map[string]interface{})
return m, ok
}
func StringToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&s))
}
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func String2Bytes(s string) []byte {
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{
Data: stringHeader.Data,
Len: stringHeader.Len,
Cap: stringHeader.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
}
func Bytes2String(b []byte) string {
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{
Data: sliceHeader.Data,
Len: sliceHeader.Len,
}
return *(*string)(unsafe.Pointer(&sh))
}
func MapStringToValue[T any](m map[string]interface{}, key string) T {
v, _ := m[key]
ret, _ := v.(T)
return ret
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。