go是强类型的语言,要求表达式的不同的类型之间必须做显式的类型转换;不过也有例外的情况:
- 当普通T类型变量向I接口类型转换时是隐式的;
- 当IX接口变量向I接口类型转换可以在编译期完成时是隐式的;
类型转换又分为类型转换
、类型断言
;不同之处在于,类型断言是对接口变量进行的操作。
类型转换
只有两个互相兼容的类型才可进行类型转换
:
<结果类型变量> := <目标类型> ( <表达式> )
转换条件
把变量x转换为T类型(T(x)
),需要满足:
- x能赋值给T类型;
- x的类型与T有相同的底层类型(underlying type);
- x的类型与T都是未命名的指针类型,且指针基于的类型是相容的;
- x的类型与T都是整数类型,或浮点类型;
- x的类型与T都是复数类型;
- x是数字或byte/rune的切片,T为string;
- x是string类型,T为byte/rune的切片;
转换示例说明:
*Point(p) // same as *(Point(p))
(*Point)(p) // p is converted to *Point
<-chan int(c) // same as <-(chan int(c))
(<-chan int)(c) // c is converted to <-chan int
func()(x) // function signature func()
(func())(x) // x is converted to func()
(func() int)(x) // x is converted to func() int
func() int(x) // x is converted to func() int (unambiguous)
类型断言
类型断言(Type Assertion)是在接口值上的操作,以检查其是否实现了期望的接口或者具体的类型。
<目标类型的值>,<布尔参数> := <表达式>.( 目标类型 ) // 安全类型断言
<目标类型的值> := <表达式>.( 目标类型 ) //非安全类型断言
对于类型断言value, ok := x.(T)
,根据ok判断x是否为T类型:
- 如果T是具体某个类型,且断言检查x的动态类型为T,则返回x的动态值(类型是T)。
- 如果T是接口类型,且断言会查x的动态类型为T,则返回值是一个类型为T的接口值。
- 如果x是nil接口值,类型断言都会失败;value赋值我T类型的零值
value, _ := x.(T)
:在转换失败时,value为T的零值
type-switch
通过type switch语句可查询接口变量的真实数据类型:
switch x.(type) {
// cases
}
判断接口是否为int或string为例(data.(type)
获取的是data的值,但case中判断的是其类型;即v获取的是data值,而switch中传入的是类型):
func VarType(data interface{}) {
// if v, ok := data.(int); ok{
// fmt.Println("int: ", v)
// result = v
// }else if v, ok := data.(string); ok{
// fmt.Println("string: ", v)
// }else {
// fmt.Printf("%v\n", data)
// }
// 直接通过switch-type判断
switch v := data.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
default:
fmt.Printf("Default: %v\n", v)
}
}
n := 0
str := "123"
ary := []int{1,2,3}
VarType(n)
VarType(str)
VarType(ary)
// int: 0
// string: 123
// Default: [1 2 3]
strconv包
strconv包提供了字符串与简单数据类型之间的类型转换功能,主要包括:
- Append 类:如 AppendBool(dst []byte, b bool)[]byte,将值转化后添加到[]byte的末尾;
- Format 类:将bool/float/int/uint 类型的转换为string(FormatInt的缩写为Itoa);如FormatBool(b bool) string;
- Parse 类:将字符串转换为bool/float/int/uint(ParseInt的缩写是Atoi);如ParseBool(str string)(value bool, err error) ,err标识是否转换成功;
- Quote 类:对字符串的 双引号/单引号/反单引号 的操作;
字符串与数字
整数与字符串间转换
i, err := strconv.Atoi("-42")
s := strconv.Itoa(-42)
i, err := strconv.ParseInt("-42", 10, 64)
u, err := strconv.ParseUint("42", 10, 64)
s := strconv.FormatInt(-42, 16)
s := strconv.FormatUint(42, 16)
布尔类型与字符串间转换
b, err := strconv.ParseBool("true")
s := strconv.FormatBool(true)
浮点数与字符串间转换
f, err := strconv.ParseFloat("3.1415", 64)
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
浮点格式化func FormatFloat(f float64, fmt byte, prec, bitSize int) string
- f:要转换的浮点数
- fmt:格式标记(b、e、E、f、g、G)
- ‘b’ (-ddddp±ddd,二进制指数)
- ‘e’ (-d.dddde±dd,十进制指数)
- ‘E’ (-d.ddddE±dd,十进制指数)
- ‘f’ (-ddd.dddd,没有指数)
- ‘g’ (数字大时同’e’,否则同’f)
- ‘G’ (数字大时同’E’,否则同’f)
- prec:精度
- 格式标记为 ‘e’,‘E’和’f’:表示小数点后的数字位数;
- 格式标记为 ‘g’,‘G’:表示总的数字位数(整数部分+小数部分);
- bitSize:指定浮点类型(32:float32、64:float64),结果会据此进行舍入。
quote
将字符串转换为双引号引起的字符串(特殊字符串替换为转移字符):
strconv.Quote(`C:\Windows`) // "C:\\Windows"
strconv.QuoteToASCII("Hello 世界!") // "Hello \u4e16\u754c\uff01"
转换函数
包中主要转换函数:
- 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 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 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 Unquote(s string) (string, error)
- func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)