接口值由两个部分组成,一个具体的类型和那个类型的值,它们被称为接口的动态类型和动态值。
当且仅当接口的动态值和动态类型都为 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 类型值
版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。
相关文章
上一篇:golang 切片中的引用