广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang泛型实现类型转换的方法实例
  • 880
分享到

Golang泛型实现类型转换的方法实例

Golang泛型golang数据类型转换golang类型转换 2022-12-30 12:12:16 880人浏览 八月长安
摘要

目录1.前言2.To String3.To Other Type3.泛型4.使用示例5.Go-huge-util参考文献总结1.前言 golang 标准库提供了很多类型转换的函数,如

1.前言

golang 标准库提供了很多类型转换的函数,如 strconv 包可完成 string 与基本数据类型之间的转换。

比如将 int 与 string 之间的互转。

// int to string
s := strconv.Itoa(i)

// string to int
i, err := strconv.ParseInt(i, 0, 64)

如果我们想完成任意类型到某一具体类型的转换,该如何实现呢?

2.To String

以 string 为,我们可以这样实现。

// ToStringE casts any type to a string type.
func ToStringE(i any) (string, error) {
	i = indirectToStringerOrError(i)

	switch s := i.(type) {
	case string:
		return s, nil
	case bool:
		return strconv.FORMatBool(s), nil
	case float64:
		return strconv.FormatFloat(s, 'f', -1, 64), nil
	case float32:
		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
	case int:
		return strconv.Itoa(s), nil
	case int64:
		return strconv.FormatInt(s, 10), nil
	case int32:
		return strconv.Itoa(int(s)), nil
	case int16:
		return strconv.FormatInt(int64(s), 10), nil
	case int8:
		return strconv.FormatInt(int64(s), 10), nil
	case uint:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint64:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint32:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint16:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint8:
		return strconv.FormatUint(uint64(s), 10), nil
	case JSON.Number:
		return s.String(), nil
	case []byte:
		return string(s), nil
	case template.html:
		return string(s), nil
	case template.URL:
		return string(s), nil
	case template.js:
		return string(s), nil
	case template.CSS:
		return string(s), nil
	case template.HTMLAttr:
		return string(s), nil
	case nil:
		return "", nil
	case fmt.Stringer:
		return s.String(), nil
	case error:
		return s.Error(), nil
	default:
		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
	}
}

其中 indirectToStringerOrError 是对指针类型的解引用,从标准库 html/template/content.go 获取。

var (
	errorType       = reflect.TypeOf((*error)(nil)).Elem()
	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
)

// Copied from html/template/content.go.
// indirectToStringerOrError returns the value, after dereferencing as many times
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
// or error,
func indirectToStringerOrError(a any) any {
	if a == nil {
		return nil
	}
	v := reflect.ValueOf(a)
	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Pointer && !v.IsNil() {
		v = v.Elem()
	}
	return v.Interface()
}

3.To Other Type

那么对其他类型我们也都要实现对应的转换函数。

// ToBoolE casts any type to a bool type.
func ToBoolE(i any) (bool, error) {
	i = indirect(i)

	switch b := i.(type) {
	case bool:
		return b, nil
	case nil:
		return false, nil
	case int:
		if i.(int) != 0 {
			return true, nil
		}
		return false, nil
	case string:
		return strconv.ParseBool(i.(string))
	default:
		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
	}
}

// ToIntE, ToInt8E, ToInt16E...

3.泛型

最终,我们可以通过泛型完成对上面多个具体类型转换函数的封装。这样我们只需要调用一个函数,便可完成对所有类型的转换。

// ToAnyE converts one type to another and returns an error if occurred.
func ToAnyE[T any](a any) (T, error) {
	var t T
	switch any(t).(type) {
	case bool:
		v, err := ToBoolE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int:
		v, err := ToIntE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int8:
		v, err := ToInt8E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int16:
		v, err := ToInt16E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int32:
		v, err := ToInt32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int64:
		v, err := ToInt64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint:
		v, err := ToUintE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint8:
		v, err := ToUint8E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint16:
		v, err := ToUint16E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint32:
		v, err := ToUint32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint64:
		v, err := ToUint64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case float32:
		v, err := ToFloat32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case float64:
		v, err := ToFloat64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case string:
		v, err := ToStringE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	default:
		return t, fmt.Errorf("the type %T is not supported", t)
	}
	return t, nil
}

如果不关心错误,可以再封装一下。

// ToAny converts one type to another type.
func ToAny[T any](a any) T {
	v, _ := ToAnyE[T](a)
	return v
}

4.使用示例

package main

import (
	"fmt"
)

func main() {
	fmt.Println(ToAny[string](1))    // "1"
	fmt.Println(ToAny[string](true)) // "true"
	fmt.Println(ToAny[string](1.1))  // "1.1"

	fmt.Println(ToAny[int]("1"))   	// 1
	fmt.Println(ToAny[int]("1.0")) 	// 1
	fmt.Println(ToAny[int](true))  	// 1

	fmt.Println(ToAny[bool]("true"))  // true
	fmt.Println(ToAny[bool]("false")) // false
	fmt.Println(ToAny[bool]("True"))  // true
	fmt.Println(ToAny[bool]("False")) // false
	fmt.Println(ToAny[bool](1))       // true
	fmt.Println(ToAny[bool](0))       // false
	fmt.Println(ToAny[bool](nil))     // false
}

5.go-huge-util

为了方便大家使用,以上相关代码已开源GitHub 工具库 go-huge-util,大家可使用 go mod 方式 import 然后使用。

import "github.com/dablelv/go-huge-util/conv"

conv.ToAny[string](1)    // "1"
conv.ToAny[string](true) // "true"
conv.ToAny[string](1.1)  // "1.1"

conv.ToAny[int]("1")   // 1
conv.ToAny[int]("1.0") // 1
conv.ToAny[int](true)  // 1

conv.ToAny[bool]("true")  // true
conv.ToAny[bool]("false") // false
conv.ToAny[bool]("True")  // true
conv.ToAny[bool]("False") // false
conv.ToAny[bool](1)       // true
conv.ToAny[bool](0)       // false
conv.ToAny[bool](nil)     // false

go-huge-util 除了类型转换,还有很多其他实用函数,如加解密、zip 等,欢迎大家使用、Star 和 Pull Request。

参考文献

github.com/dablelv/go-huge-util

总结

到此这篇关于Golang泛型实现类型转换的文章就介绍到这了,更多相关Golang泛型类型转换内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Golang泛型实现类型转换的方法实例

本文链接: https://www.lsjlt.com/news/176310.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang泛型实现类型转换的方法实例
    目录1.前言2.To String3.To Other Type3.泛型4.使用示例5.go-huge-util参考文献总结1.前言 Golang 标准库提供了很多类型转换的函数,如...
    99+
    2022-12-30
    Golang泛型 golang数据类型转换 golang类型转换
  • golang interface类型转换怎么实现
    在Go语言中,可以通过类型断言来实现接口类型的转换。 使用类型断言的语法为: value, ok := interfaceVar.(...
    99+
    2023-10-20
    golang
  • java泛型中类型擦除的转换示例
    这篇文章给大家分享的是有关java泛型中类型擦除的转换示例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、浮点类型,用...
    99+
    2023-06-14
  • Golang 实现interface类型转string类型
    看代码吧~ // Strval 获取变量的字符串值 // 浮点型 3.0将会转换成字符串3, "3" // 非数值或字符类型的变量将会被转换成JSON格式字符串 func Str...
    99+
    2022-11-12
  • golang类型转换的方法有哪些
    在Golang中,类型转换的方法有以下几种: 默认类型转换:可以通过将一个类型直接赋值给另一个类型来进行类型转换。例如:var ...
    99+
    2023-10-22
    golang
  • java泛型数组转换类型的示例分析
    小编给大家分享一下java泛型数组转换类型的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、浮点类型,用来表示小数的数据...
    99+
    2023-06-14
  • Python数据类型转换实现方法
    目录基本类型转换python中的C语言数据类型python中的struct库python中的binascii库python中的libnum神器基本类型转换 python3与pytho...
    99+
    2022-12-08
    Python数据类型转换 Python类型转换
  • Python容器类型转换的3种方法实例
    目录前言一、tuple()二、list()三、set()扩展总结前言 其实容器类型的转换可以说是数据类型的转换,涉及到三个函数,分别是tuple()、list()、set()。为什么...
    99+
    2022-11-10
  • java泛型怎么转换为实体类
    在Java中,可以使用泛型来定义一个类型,在需要转换为实体类时,可以使用反射机制来实现。首先,假设有一个泛型类MyClass,其中T...
    99+
    2023-10-18
    java
  • MybatisPlus字段类型转换的实现示例
    目录resultMap的作用是什么mybatisPlus如何完成字段映射自动映射@TableField是能够指定jdbcType的mybatis如何完成查询参数转换先来回忆下在myb...
    99+
    2023-03-15
    MybatisPlus 字段类型转换 MybatisPlus 类型转换
  • MySQL显式类型转换实例
    小编给大家分享一下MySQL显式类型转换实例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!undefined在之前的文章中,我们...
    99+
    2022-10-18
  • C#类型转换实例分析
    这篇“C#类型转换实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#类型转换实例分析”文章吧。C# 类型转...
    99+
    2023-06-17
  • java如何实现类型转换与强制类型转换
    这篇文章主要介绍了java如何实现类型转换与强制类型转换,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java类型转换与强制类型转换如果你以前有编程经验,那么你已经知道把一种...
    99+
    2023-06-03
  • Java中Object转换为List类型的实现方法
    前言 在很多项目编写过程中会使用Map<?>类型来进行参数的传递。为了能够让更多的类型放入value中,实例化的类型往往是Map<String, Obje...
    99+
    2022-11-11
  • JavaScript类型转换的方法
    这篇文章主要讲解了“JavaScript类型转换的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript类型转换的方法”吧!  ...
    99+
    2022-10-19
  • golang中常见的类型转换方法有哪些
    本篇内容介绍了“golang中常见的类型转换方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!数字类型转换在Golang中,数字类型转...
    99+
    2023-07-05
  • Pandas类型转换astype()的实现
    Python中和Pandas中数据类型对应关系如下: 果数据是纯净的数据,可以转化为数字astype基本也就是两种用作,数字转化为单纯字符串,单纯数字的字符串转化为数字,含有其他的...
    99+
    2022-11-11
  • numpy数据类型dtype转换实现的示例
    小编给大家分享一下numpy数据类型dtype转换实现的示例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!导入numpy>>> imp...
    99+
    2023-06-14
  • struts2中类型转换实例代码
    类型转换        所有的页面与控制器传递的数据都是String类型,在对其进行处理时可能会用到各种的数据类型,程序无法自动完成数据类型的转换,这就需要我们在代码中进...
    99+
    2023-05-31
    struts2 类型转换 中类
  • GoFrame框架Scan类型转换实例
    目录前言方法定义自动识别转换Struct结构体示例代码运行结果自动识别转换Struct数组示例代码运行结果自动识别转换Map示例代码运行结果自动识别转换Map数组示例代码运行结果总结...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作