go语言学习笔记(六)——变量类型检查

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32023305/article/details/82113468
  • 问题:怎样判断一个变量的类型

以demo11为示例

// demo11.go
package main
 
import (
	"fmt"
)
 
var container = []string{"zero", "one", "two"}
func main() {
	container:=map[int]string{0:"zero", 1:"one", 2:"two"}
	fmt.Printf("The element is %q.\n", container[1])
}

那么,怎样在打印其中元素之前正确判断变量constainer的类型?

答案是使用“类型断言”表达式。具体怎么写呢?

value, ok:=interface{}(container).([]string)

它包括了用来把constainer变量的值转换为空接口值的interface{}(container)。

以及一个用来判断前者的类型是否为切片类型[]string的.([]string)。

这个表达式的结果可以被赋给两个变量,在这里由value和ok代表。变量ok是布尔类型的,它将代表类型判断的结果,true或false。如果是true,那么被判断的值将会被自动转换为[]string类型的值,并赋给变量value,否则value将被赋予nil

问题解析

说明一下,类型断言表达式的语法形式是x.(T)。其中的x代表要被判断类型的那个值。这个值当下的类型必须是接口类型,不过具体是哪个接口类型其实是无所谓的。

所以我们需要将示例中的container变量类型转换为接口类型,而interface{}代表空接口,任何类型都是它的实现类型,任何类型的值都可以很方便地被转换为空接口的值,具体语法为interface{}(x)

注:一对不包裹任何东西的花括号,除了可以代表空的代码块之外,还可以用于表示不包含任何内容的数据结构(或者说数据类型)
  • 类型转换规则中的注意点

语法形式:T(x) //T为目标类型,x为源值

1.对于整数类型值,整数常量之间的类型转换,原则上只要源值在目标类型的可表示范围就是合法的

       举例说明:之所以uint8(255)可以把无类型的常量255转换为uint8类型的值,是因为255在[0,255]的范围内

注意:整数都是以补码的形式存储的,大范围数转小范围数转换时会直接截断。比如int16类型的-255的补码1111111100000001。将其转换为int8类型时,go语言会把最左边的8位二进制数直接截断,得到00000001,所以转换完值为1了。类似的规则还有,当把一个浮点数类型的值转换为整数类型值时,前者的小数部分会被全部截掉

2.在整数值转换为string类型时,被转换的整数值应该可以代表一个有效的Unicode代码点,否则转换结果将会是“�”

         举例说明:string(-1),-1无法代表一个有效的Unicode代码点,所以总会得到�

3.string类型与各种切片类型之间的互转

一个值在从string类型向[]byte类型转换时代表着以UTF-8编码的字符串会被拆分成零散,独立的字节,除了与ASCII编码兼容的那部分字符集,以UTF-8编码的某个单一字节是无法代表一个字符的。

string([]byte{'\xe4', '\xbd', '\xa0', '\xe5', '\xa5', '\xbd'}) // 你好

'\xe4', '\xbd', '\xa0'合在一起代表“你”,'\xe5', '\xa5', '\xbd'代表“好”

一个值从string类型向[]rune类型转换时,代表着字符串会被拆分成一个个的Unicode字符,一个字符代表一个汉字。

  • 什么是别名类型?什么是潜在类型

别名类型:type MyString = string

这条声明语句,MyString是string的别名类型。顾名思义,别名类型与其源类型的区别只是在名称上,他们是完全相同的,别名类型主要是为了代码重构而存在的。具体可见https://colobu.com/2017/06/26/learn-go-type-aliases/

Go语言内建的基本类型中就存在两个别名类型。byte是uint8的别名类型,而rune是int32的别名类型

潜在类型:type MyString2 string

和别名类型不同的是潜在类型语法中没有等号,这里的MyString是一个新的类型,不同于其他的任何类型,这种方式也可以被叫做对类型的再定义,string可以被称为MyString2的潜在类型。

潜在类型的值之间是可以进行类型转换的,如本例中MyString2类型的值可以跟string类型的值互相转换,

但是集合类的类型[]MyString2与[]string就不行,因为他们的潜在类型就不同了,分别是MyString2和string。

即使两个类型的潜在类型相同,他们的值之间也不能进行判断或比较,他们的变量之间也不能互相赋值。

具体对比看如下代码

package main

type D = int
type I int

func main() {
    v := 100
    var d D = v    // 不报错
    var i I = v    // 报错
}

猜你喜欢

转载自blog.csdn.net/sinat_32023305/article/details/82113468