golang中的类型转换那些事

由于golang是一门强类型的语言, 所以我们在golang的开发中不可避免的会对一些数据类型进行手动转换,以适应我们的业务需求。 

golang中类型转换的途径大致有4种,强制转换,类型断言,类型匹配 还有使用strconv包中提供的转换函数, 下面我们分别举例说明。

1. 强制转换   类型(变量名)

强制类型转换一般用于对已知类型(非any类型)进行高低精度之间的转换,如从 int 转换为 int64, 或者 int转换为 uint ,  float32转换为 float64 这类的转换, 这类型的转换较为简单,

  • 转换语法类型(变量名)   
  • 语法说明:这里的类型即是你要转换到的类型,变量名是你要转换的变量名称
  • 强制转换示例
var  x1 int = 10 // 声明一个int类型变量 x1 并赋值为 10

x2 := uint64(x1) // 将x1强制转换为uint64类型并赋值给x2
  • 细节说明:
  1.  从高精度到低精度转换会有丢失精度的风险;
  2. 对于any类型(即空接口类型interface{})的数据不能使用强制转换。

2. 类型断言   i变量名.(类型)

类型断言一个专门用于any类型(也就是 interface{}空接口类型,他们是一个东西)的数据类型转换的。 

语法:  i变量名.(类型

说明: 这里的 i变量名 指的就是你自己定义的interface{} 类型的变量名,注意必须是空接口类型,其他类型的变量名不能应用类型断言!!

这里的 类型   则可以是任意的类型,包括内置类型,和你自己定义的结构体或者接口都可以继续断言。 当然 any 也可以作为这里的类型进行断言的

类型断言示例:


func ExampleTypeAsserts() {

	var ival1 interface{} = 1
	// 对变量 ival1 进行 int数据类型断言, 断言后可返回2个值, 第二个值表示是否断言成功, 第一个是断言成功后的断言类型的值
	if int1, ok := ival1.(int); ok {
		fmt.Printf("%v 的类型是: %T \n", int1, int1) // output: 1 的类型是: int
	}
	// 如果你确定这个类型就是某个类型,断言也可以只用一个变量接收, 这种情况下,如果断言失败,则会抛panic异常,所以这种方式要慎用!
	// int2 := ival1.(int64) // 这个就会抛异常 panic: interface conversion: interface {} is int, not int64
	int2 := ival1.(int) // ok

	fmt.Printf("%v 的类型是: %T \n", int2, int2) // output: 1 的类型是: int


	// any 类型是interface{} 的一个别名 他们是一个东西
	var tsx any
	tsx = time.Now()
	// 对象断言
	if ts,ok:=tsx.(time.Time);ok {
		// 这里ts就是断言成功后的time类型的对象, 我们就可以调用他的方法 ts.Format(time.RFC3339)
		// 但是tsx 里面是不能直接调用time方法的, 虽然你知道你赋值了一个时间对象给他,这点一定要注意!!
		fmt.Printf("ts的类型为 %T , 值为: %v", ts, ts.Format(time.RFC3339)) // output: a
	}

}

3. 类型匹配  i变量名.(type)

这个也是专门用于处理any类型的数据的, 需要注意的是 i变量名.(type) 只能用在 switch语句上面。 他用于对any类型的数据进行类型匹配和处理。 如我们需要对不同类型的变量进行不同的处理时就用它。

语法:  switch  i变量名.(type) {  case xxx:   }

说明: i变量名 这个和上面的一样; .(type)  这时固定的用法,用于获取i变量名对应的类型; 后面的case语句就是 定义不同类型时的处理逻辑的,case 后面的 xxx 这个是你要判断的 类型,这里可以是任意的类型,包括内置类型或者你自己定义的类型或者接口

示例:


func ExampleTypeType() {
	var inter1 interface{}
	inter1 = 88.8 // 我们给这个变量 赋值一个float64类型的数, go里面对于否点数默认为 float64类型
	switch inter1.(type) {
	case int:
		fmt.Printf("inter1: %v 是int类型的数据", inter1) // 这个不会被执行
	case float64:
		fmt.Printf("inter1: %v 是float64类型的数据", inter1) // output: inter1: 88.8 是float64类型的数据
	case time.Time:
		fmt.Printf("inter1: %v 是time.Time类型的数据", inter1) // 这个也不会被执行
		
	}

}

4.strconv提供的转换函数

这个官方提供的包里面包含了非常多的转换函数,其中较为常用的是ParseXXX, FormatXXX 和 Atoi, 和 Itoa, 他们的使用相对比较简单,看看函数定义就可以使用。

strconv.Atoi("123") // 将字符串转换为int

strconv.Itoa(456) //将int转换为字符串

下面是strconv中所定义的函数一览表

func AppendBool(dst []byte, b bool) []byte
func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte
func AppendInt(dst []byte, i int64, base int) []byte
func AppendQuote(dst []byte, s string) []byte
func AppendQuoteRune(dst []byte, r rune) []byte
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte
func AppendQuoteRuneToGraphic(dst []byte, r rune) []byte
func AppendQuoteToASCII(dst []byte, s string) []byte
func AppendQuoteToGraphic(dst []byte, s string) []byte
func AppendUint(dst []byte, i uint64, base int) []byte
func Atoi(s string) (int, error)
func CanBackquote(s string) bool
func FormatBool(b bool) string
func FormatComplex(c complex128, fmt byte, prec, bitSize int) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func IsGraphic(r rune) bool
func IsPrint(r rune) bool
func Itoa(i int) string
func ParseBool(str string) (bool, error)
func ParseComplex(s string, bitSize int) (complex128, error)
func ParseFloat(s string, bitSize int) (float64, error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (uint64, error)
func Quote(s string) string
func QuoteRune(r rune) string
func QuoteRuneToASCII(r rune) string
func QuoteRuneToGraphic(r rune) string
func QuoteToASCII(s string) string
func QuoteToGraphic(s string) string
func QuotedPrefix(s string) (string, error)
func Unquote(s string) (string, error)
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
type NumError
func (e *NumError) Error() string
func (e *NumError) Unwrap() error

总结:go语言中的类型转换和我们常用的java, rust, c, php等语言的类型转换可谓是完全不一样,他使用了自己独有的语法模式。对于新手而言前面3种模式很容易搞混淆,需要特别注意。 另外在进行类型断言时 对于断言后的结果他是可以有2个接收参数,也可以只有一个接收参数!搞清楚他们的区别很重要,这点需要特别注意。至于strconv包里面提供的函数的使用就太简单了,大家自己看看函数原型就能用。

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值