day9接口 接口值和接口约束
parent
cf58df8457
commit
17a8ace39d
|
@ -0,0 +1,68 @@
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in New Issue