类型断言
- 接口赋值之后,保存了数据类型
- 访问接口底层的具体值,通过类型断言, case1
- 类型断言返回两个值,底层值和断言是否成功
- element.(type)语法不能在switch外的任何逻辑里面使用,如果你要在switch外面判断一个类型就使用comma-ok
//case1
package main
import "fmt"
func main() {
var i interface{} = 0.45
// fmt.Println(i.(type)) //报错(panic)
//s := i.(string) //报错(panic)
//fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
f, ok := i.(float64)
fmt.Println(f, ok)
}
fmt的普遍接口Stringer
- 任何类型定义了该接口,则可以通过fmt打印值 case3
//case2
type Stringer interface {
String() string
}
//case3
package main
import "fmt"
type myComplex complex64
func (v myComplex) String() string {
return "this is a complex"
}
func main() {
t := myComplex(2)
fmt.Println(t)
}
练习题-Stringer
//case4
package main
import "fmt"
import "strconv"
type IPAddr [4]byte
// TODO: 给 IPAddr 添加一个 "String() string" 方法
func (t IPAddr) String() string{
var res string
for i:=0; i <4; i++ {
res += strconv.Itoa(int(t[i]))+"."
}
return res[:len(res)-1]
}
func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip)
}
}
https://tour.go-zh.org/methods/19
错误
- 函数会返回error值,error为nil表示成功,非nil的error表示失败
练习题-错误
- 修改 Sqrt 函数,使其接受一个负数时,返回 ErrNegativeSqrt 值
//case5
package main
import (
"fmt"
"math"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number")
}
func Sqrt(x float64) (float64, error) {
if x < 0 {
return x, ErrNegativeSqrt(x)
} else {
return math.Sqrt(x), nil
}
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
Reader
- io 包指定了 io.Reader 接口,它表示从数据流的末尾进行读取。
- Read 用数据填充给定的字节切片并返回填充的字节数和错误值。在遇到数据流的结尾时,它会返回一个 io.EOF 错误。
//case6
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
}
}
}
练习题-Reader
- 做不出来这个题目,是因为不懂import进来的reader的Validate函数:https://github.com/golang/tour/blob/master/reader/validate.go
//case7
package main
import "golang.org/x/tour/reader"
type MyReader struct{}
func (e MyReader) Read(b []byte) (int, error) {
b[0] = 'A'
return 1, nil
}
// TODO: 给 MyReader 添加一个 Read([]byte) (int, error) 方法
func main() {
reader.Validate(MyReader{})
}
练习题-rot13Reader
- 实现 Read 方法以满足 io.Reader
- io.Reader 接口有一个 Read 方法:
func (T) Read(b []byte) (n int, err error) - https://en.wikipedia.org/wiki/ROT13
//case8
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (e rot13Reader) Read(b []byte)(int, error) {
n, error := e.r.Read(b)
for i:=0; i<n; i++ {
switch {
case b[i] >= 'A' && b[i] <= 'M':
b[i] += 13
case b[i] >= 'N' && b[i] <= 'Z':
b[i] -= 13
case b[i] >= 'a' && b[i] <= 'm':
b[i] += 13
case b[i] >= 'n' && b[i] <= 'z':
b[i] -= 13
}
}
return n, error
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
Image接口
- https://blog.csdn.net/weixin_42810335/article/details/107459094
//case9
package main
import ("golang.org/x/tour/pic"
"image"
"image/color"
)
type Image struct{
width int
height int
}
func (i Image) Bounds() image.Rectangle {
return image.Rect(0,0, i.width, i.height)
}
func (i Image) ColorModel() color.Model {
return color.RGBAModel
}
func (i Image) At(posx,posy int) color.Color {
return color.RGBA{uint8(posx), uint8(posy), uint8(255),uint8(255)}
}
func main() {
m := Image{100,200}
pic.ShowImage(m)
}