上一篇介绍了类型断言可以使用在interface{}中,可以使用类型断言来判断传递过来的参数是怎样的数据类型。

那么为什么可以通过断言来判断数据类型,实际上与变量的内部构造有关系。

变量的内部构造(pair)

当我们定义了一个变量,其内部分为两个部分:

image.png

  • 变量的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)
}

运行结果:
image.png
可以看到结果成功打印出了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()

}

运行结果:
image.png

总结下来就是当进行赋值传递时,变量的pair是不会改变的。

变量中的pair是为接下来的反射做铺垫。

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏