一、Stringer
fmt包中定义的Stringer是最普遍的接口之一。
type Stringer interface { String() string }
Stringer是一个可以用字符串描述自己的类型。fmt包都通过此接口来打印值。
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func main() {
a := Person{"Arthur Dent", 42}
z := Person{"Zaphod Beeblebrox", 9001}
fmt.Println(a, z) //Arthur Dent (42 years) Zaphod Beeblebrox (9001 years)
}
二、错误
Go程序使用error值来表示错误状态。
与fmt.Stringer类似,error类型是一个内建接口:
type error interface {
Error() string
}
与fmt.Stringer类似,fmt包也会根据对error的实现来打印值。
通常函数会返回一个error值,调用它的代码应当判断这个错误是否等于nil来进行错误处理。
error为nil时表示成功;非nil的error表示失败。
package main
import (
"fmt"
"time"
)
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run() error {
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err) //at 2024-07-23 18:29:03.6192234 +0800 CST m=+0.003278201, it didn't work
}
}
三、Readers
io包指定了io.Reader接口,它表示数据流的读取端。
Go标准库包含了该接口的许多实现,包括文件、网络连接、压缩和加密等等。
io.Reader接口有一个Read方法:
func (T) Read(b []byte) (n int, err error)
Read用数据填充给定的字节切片并返回填充的字节数和错误值。在遇到数据流动的结尾时,会返回一个io.EOF错误。
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for {
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
fmt.Printf("b[:n] = %q\n", b[:n])
if err == io.EOF {
break
}
}
}
/*
n = 8 err = <nil> b = [72 101 108 108 111 44 32 82]
b[:n] = "Hello, R"
n = 6 err = <nil> b = [101 97 100 101 114 33 32 82]
b[:n] = "eader!"
n = 0 err = EOF b = [101 97 100 101 114 33 32 82]
b[:n] = ""