golang interface 类型值

文章目录 (?) [+]

    接口值由两个部分组成,一个具体的类型和那个类型的值,它们被称为接口的动态类型和动态值。

    当且仅当接口的动态值和动态类型都为 nil 时,接口类型值才为 nil 。

    案例说明

    package main
    
    import "fmt"
    
    type Service interface {
        Name()
    }
    
    type MySql struct{}
    
    func (MySql) Name() {}
    
    func test(s Service) {
        // 因为 m2 赋值给了 s
        // s 的动态类型为 *MySql,其值为 nil,也即 s 为 (*MySql)(nil),故此处判断为 true
        if s != nil {
            fmt.Printf("value: %v type: %T\n", s, s)
        }
    }
    
    func main() {
        // 变量的类型在声明时指定且不能改变称为静态类型
        // 接口类型的静态类型就是接口本身,接口没有静态值,它指向的是动态值
        // s 的动态值为 nil 且为静态类型 Service
        var s Service
        fmt.Printf("value: %v type: %T\n", s, s)
    
        // 这个赋值过程调用了一个具体类型到接口类型的隐式转换,这和显式的使用 Service(MySql) 是等价的
        // s 的动态类型为 MySql,其值为结构体 {}
        s = MySql{}
        fmt.Printf("value: %v type: %T\n", s, s)
    
        // m1 为静态类型 MySql,其值为结构体 {}
        var m1 MySql
        fmt.Printf("value: %v type: %T\n", m1, m1)
    
        // m2 为静态类型 *MySql,其值为 nil
        var m2 *MySql
        fmt.Printf("value: %v type: %T\n", m2 == nil, m2)
    
        // s 为动态类型 *MySql,其值为 nil,也即 s 为 (*MySql)(nil)
        s = m2
        test(m2)
    
        // 当且仅当动态值和动态类型都为 nil 时,接口类型值才为 nil
        fmt.Printf("value: %v value: %v type: %T\n", s == nil, s == (*MySql)(nil), s)
    }
    /*
    value: <nil> type: <nil>
    value: {} type: main.MySql
    value: {} type: main.MySql
    value: true type: *main.MySql
    value: <nil> type: *main.MySql
    value: false value: true type: *main.MySql
    */


    本文标题:golang interface 类型值
    本文链接:https://lanseyujie.com/post/golang-interface-type-value.html
    版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。
    点赞 0 分享 0