Files
bulma/interface_type.go

82 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import "fmt"
// 定义基础接口
type Reader interface {
Read() string
}
// 定义扩展接口(方法集包含Reader)
type ReadWriter interface {
Reader // 嵌入接口,继承Read()方法
Write(string)
}
// 实现ReadWriter接口(隐式实现Reader
type File struct {
content string
}
func (f *File) Read() string {
return f.content
}
func (f *File) Write(s string) {
f.content = s
}
// 接口作为函数参数
func readData(r Reader) {
fmt.Println("读取数据:", r.Read())
}
func main() {
// 隐式实现与接口赋值
var f *File = &File{content: "test data"}
var r Reader = f // File实现Reader,可赋值
var rw ReadWriter = f // File实现ReadWriter,可赋值
fmt.Printf("Reader Read: %s\n", r.Read()) // 输出test data
rw.Write("测试数据")
fmt.Printf("ReadWriter Read: %s\n", rw.Read()) // 输出测试数据
// 类型断言(判断接口存储的具体类型)
if file, ok := r.(*File); ok {
file.Write("new data")
fmt.Printf("After Write: %s\n", r.Read()) // 输出new data
}
// 接口作为函数参数
readData(f) // File实现了Reader接口,可以传递
// 空接口使用
var any interface{}
any = 100
fmt.Printf("any type: %T, value: %v\n", any, any) // 输出int, 100
any = "hello"
fmt.Printf("any type: %T, value: %v\n", any, any) // 输出string, hello
// 空接口与nil的陷阱
var p *int = nil
var i interface{} = p
fmt.Printf("p == nil? %t, i == nil? %t\n", p == nil, i == nil) // 输出true, false
// 说明:
// 当一个接口变量被赋值时,它会存储两个信息:
// 动态类型 (dynamic type)
// 动态值 (dynamic value)
// p 是一个指向 int 的指针,其值为 nil
// 当将 p 赋值给接口变量 i 时:
// i 的动态类型是 *int
// i 的动态值是 nil(来自 p 的值)
// 但是 i 本身不是 nil 接口,而是一个包含 (*int, nil) 的接口
// i (interface{}):
// ├── type: *int
// └── value: nil (p的值)
//
// p (*int):
// └── value: nil
var emptyInterface interface{} // 这个才是 == nil 的
fmt.Println("emptyInterface == nil?", emptyInterface == nil)
}