GolangStudy/src/study/day9Interface/InterfaceValue.go

69 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"bytes"
"fmt"
"io"
"os"
)
func main() {
var w io.Writer
fmt.Printf("(%T, %[1]v)\n", w)
w = os.Stdout
w = io.Writer(os.Stdout)
fmt.Printf("(%T, %[1]v)\n", w)
w.Write([]byte("hello, writer\n")) // 向屏幕输出了hello, writer
fmt.Printf("(%T, %[1]v)\n", w)
w = new(bytes.Buffer)
fmt.Printf("(%T, %[1]v)\n", w)
w.Write([]byte("hello")) // 向缓冲区写入了hello
fmt.Printf("(%T, %[1]v)\n", w)
w = nil
fmt.Printf("(%T, %[1]v)\n", w)
// 这里按照我的理解w是一个接口接口的值是一个指针指向一个实现了Write()方法的结构体
// os.Stdout是一个变量保存了 os.NewFile()这个函数的返回值这个函数返回的是一个File结构体指针
// 这个File结构体实现了Write()方法
// 按照接口的约束条件, w可以使用Write()方法
// 但不能使用File结构体里实现的其他方法比如Close()方法
// 这里不管是w = os.Stdout还是w = new(bytes.Buffer),
// 都是将w的值改变了但是w的类型是不变的都是io.Writer
// 所以接口的类型是不变的,接口的约束仍然存在
// 接口的值在我看来很像是一个指针,指向一个实现了接口的某一个结构体
// 这个结构体可以是一个File结构体也可以是一个Buffer结构体
// 实现的方法也不一样,所以调用的结果也不一样
type name struct {
firstName string
lastName string
}
var x, y interface{}
x = name{"John", "Doe"}
y = name{"John", "Doe"}
fmt.Println(x == y) // true
// 这里的x和y是两个接口接口的值是两个结构体
// 两个结构体的值是一样的所以x和y是相等的
x = &name{"John", "Doe"}
y = &name{"John", "Doe"}
fmt.Println(x == y) // false
// 这里的x和y是两个接口接口的值是两个结构体指针
// 两个结构体指针的值是不一样的所以x和y是不相等的
// Go中的接口的nil值和指针类型的nil值是不一样的
type Empty struct{}
var z interface{}
var AEmpty Empty
var p *int
fmt.Printf("%T, %[1]v\n", AEmpty)
fmt.Println(z == AEmpty) // false
fmt.Println(z == nil) // true
fmt.Println(p == nil) // true
fmt.Println(z == p) // false
// 在实际开发中, 要尽量用nil代替空指针去返回
// see : 【golang 踩坑之Shit box】 https://www.bilibili.com/video/BV1G8411j7Q6
}