上一篇介绍了类型断言可以使用在interface{}
中,可以使用类型断言来判断传递过来的参数是怎样的数据类型。
那么为什么可以通过断言来判断数据类型,实际上与变量的内部构造有关系。
变量的内部构造(pair)
当我们定义了一个变量,其内部分为两个部分:
- 变量的type和value合并称作pair,当新建了一个变量,便会有两个指针指向type和value
- 变量的type只能为static type和consrete type中的一种。
- 而反射指的是通过变量找到当前变量是静态类型还是具体类型,也允许通过当前变量得到value。
案例1
变量的type和value可以随着赋值一直传递下去
例如:
package main
import "fmt"
func main() {
var a string // 定义一个变量
a = "abc" // 变量内部的pair <staticType:string, value:"abc">
var allType interface{} // 声明万能类型
allType = a // 将a变量赋值给该万能类型,此时allType内部的pair也为 <staticType:string, value:"abc">
str, _ := allType.(string)
fmt.Println(str)
}
运行结果:
可以看到结果成功打印出了a的value,说明不管怎么传递,都会将a变量的tpye和value传递下去,因此可以使用断言找到a的value。
所以在变量赋值的过程中pair值会传递下去,保持不变。
案例2
package main
import "fmt"
type Reader interface {
ReadBook()
}
type Writer interface {
WriteBook()
}
// 具体的类型
type Book struct {
}
// 定义类的读书方法
func (this *Book) ReadBook() {
fmt.Println("Read a Book")
}
// 定义类的写书方法
func (this *Book) WriteBook() {
fmt.Println("Write a Book")
}
func main () {
// b: pair<type: Book, value:Book{}地址>
b := &Book{}
// r: pair<type: , value:>
var r Reader
// r: pair<type:Book, value:book{}地址>
r = b
r.ReadBook()
var w Writer
// r的pair为<pair:Book, value:book{}地址>
w = r.(Writer) // 此处的断言为什么会成功? 因为w和r的type是一致的
w.WriteBook()
}
运行结果:
总结下来就是当进行赋值传递时,变量的pair是不会改变的。
变量中的pair是为接下来的反射做铺垫。
此处评论已关闭