Go基础6 程序实体之类型判断

728 阅读4分钟

怎样判断一个变量的类型?
我们可以使用“类型断言”表达式来进行变量类型的判断。

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

表达式解析:

  1. interface{}(container): 用来把container变量的值转换为空接口值
  2. .([]string): 用于判断前者的类型是否为切片类型 []string 的
  3. 这个表达式的结果可以被赋给两个变量,在这里由value和ok代表。变量ok是布尔(bool)类型的,它将代表类型判断的结果,true或false。
  4. 如果是true,那么被判断的值将会被自动转换为[]string类型的值,并赋给变量value,否则value将被赋予nil(即“空”)。
  5. 类型断言表达式的结果,可以只被赋给一个变量,在这里是value, 但是不建议这样做,当判断为否时,程序会抛出panic。

image.png

eg:

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])
}

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

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

类型转换的三个注意点

  1. 对于整数类型值、整数常量之间的类型转换,原则上只要源值在目标类型的可表示范围内就是合法的。
uint8(255)可以把无类型的常量255转换为uint8类型的值,是因为255在[0, 255] 的范围内。

var srcInt = int16(-255)
dstInt := int8(srcInt)

整数在 Go 语言以及计算机中都是以补码的形式存储的。这主要是为了简化计算机对整数的运算过程。补码其实就是原码各位求反再加 1。

比如,int16类型的值-255的补码是1111111100000001。如果我们把该值转换为int8类型的值,那么 Go 语言会把在较高位置(或者说最左边位置)上的 8 位二进制数直接截掉,从而得到00000001。
又由于其最左边一位是0,表示它是个正整数,以及正整数的补码就等于其原码,所以dstInt的值就是1。

当整数值的类型的有效范围由宽变窄时,只需在补码形式下截掉一定数量的高位二进制数即可。
当把一个浮点数类型的值转换为整数类型值时,前者的小数部分会被全部截掉。
  1. 虽然直接把一个整数值转换为一个string类型的值是可行的,但值得关注的是,被转换的整数值应该可以代表一个有效的 Unicode 代码点,否则转换的结果将会是"�"(仅由高亮的问号组成的字符串值)。比如string(-1)就会得到一个未知字符。

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

string类型向[]byte类型转换时代表着以 UTF-8 编码的字符串会被拆分成零散、独立的字节。
除了与 ASCII 编码兼容的那部分字符集,以 UTF-8 编码的某个单一字节是无法代表一个字符的。
string([]byte{'\xe4', '\xbd', '\xa0', '\xe5', '\xa5', '\xbd'}) // 你好

string类型向[]rune类型转换时代表着字符串会被拆分成一个个Unicode 字符。
string([]rune{'\u4F60', '\u597D'}) // 你好

别名类型与潜在类型
别名类型
我们可以用关键字type声明自定义的各种类型。当然了,这些类型必须在 Go 语言基本类 型和高级类型的范畴之内。在它们当中,有一种被叫做“别名类型”的类型。我们可以像下 面这样声明它:

//MyString是string类型的别名类型。顾名思义,别名类型与其源类型的区别恐怕只是在名称上,它们是完全相同的。
type MyString = string

Tips: byte是uint8的别名类型,而rune是int32的别名类型,别名类型主要用于代码重构: golang.org/design/1813…

再类型与潜在类型
如果我们去掉=, 这样就不是声明一个别名类型了,而是把string类型再定义成了另外一个类型MyString2。而string可以被称为MyString2的潜在类型。潜在类型的含义是,某个类型在本质上是哪个类型。

潜在类型特点:

  1. 潜在类型相同的不同类型的值之间是可以进行类型转换的。因此,MyString2类型的值与string类型的值可以使用类型转换表达式进行互转。
  2. 对于集合类的类型[]MyString2与[]string来说这样做却是不合法的,因为[]MyString2与[]string潜在类型不同,分别是[]MyString2和[]string。
  3. 即使两个不同类型的潜在类型相同,它们的值之间也不能进行判等或比较,它们的变量之间也不能赋值。
type MyString2 string

image.png