zwvista

导航

Go语言学习笔记(3)

接口

type Abser interface {
    Abs() float64
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}
type Vertex struct {
    X, Y float64
}
func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f  // a MyFloat implements Abser
fmt.Println(a.Abs()) // 1.4142135623730951
a = &v // a *Vertex implements Abser
fmt.Println(a.Abs()) // 5
// In the following line, v is a Vertex (not *Vertex)
// and does NOT implement Abser.
// a = v
// 不需要显式声明结构 T 实现了接口 I
type I interface {
    M()
}
type T struct {
    S string
}
// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M() {
    fmt.Println(t.S)
}
var i I = T{"hello"}
i.M() // hello
// 接口类型的变量
type I interface {
    M()
}
type T struct {
    S string
}
func (t *T) M() {
    fmt.Println(t.S)
}
type F float64
func (f F) M() {
    fmt.Println(f)
}
func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
var i I
i = &T{"Hello"}
describe(i) // (&{Hello}, *main.T)
i.M() // Hello
i = F(math.Pi)
describe(i) // (3.141592653589793, main.F)
i.M() // 3.141592653589793
// 接口类型的变量的值为 nil
type I interface {
    M()
}
type T struct {
    S string
}
func (t *T) M() {
    if t == nil {
        fmt.Println("<nil>")
        return
    }
    fmt.Println(t.S)
}
func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
var i I
var t *T
i = t
describe(i) // (<nil>, *main.T)
i.M() // <nil>
i = &T{"hello"}
describe(i) // (&{hello}, *main.T)
i.M() // hello
// 接口类型的变量的值为 nil
type I interface {
    M()
}
func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
var i I
describe(i) // (<nil>, <nil>)
// i.M() // error
// 通用接口类型 interface{}
func describe(i interface{}) {
    fmt.Printf("(%v, %T)\n", i, i)
}
var i interface{}
describe(i) // (<nil>, <nil>)
i = 42
describe(i) // (42, int)
i = "hello"
describe(i) // (hello, string)

类型断言

var i interface{} = "hello"
s := i.(string)
fmt.Println(s) // hello
s, ok := i.(string)
fmt.Println(s, ok) // hello true
f, ok := i.(float64)
fmt.Println(f, ok) // 0 false
f = i.(float64) // panic
fmt.Println(f)
func do(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Twice %v is %v\n", v, v*2)
    case string:
        fmt.Printf("%q is %v bytes long\n", v, len(v))
    default:
        fmt.Printf("I don't know about type %T!\n", v)
    }
}
do(21) // Twice 21 is 42
do("hello") // "hello" is 5 bytes long
do(true) // I don't know about type bool!

Stringer 接口

// 标准接口 Stringer
type Stringer interface {
    String() string
}
type Person struct {
    Name string
    Age  int
}
func (p Person) String() string {
    return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
a := Person{"Arthur Dent", 42}
z := Person{"Zaphod Beeblebrox", 9001}
fmt.Println(a, z) // Arthur Dent (42 years) Zaphod Beeblebrox (9001 years)

error 接口

// 标准接口 error
type error interface {
    Error() string
}
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" }
}
if err := run(); err != nil {
    fmt.Println(err) // at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't work
}

Reader 接口

// 标准接口 Reader
type Reader interface {
    func (T) Read(b []byte) (n int, err error)
}
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] = ""
*/

Image 接口

// 标准接口 Image
type Image interface {
    ColorModel() color.Model
    Bounds() Rectangle
    At(x, y int) color.Color
}
m := image.NewRGBA(image.Rect(0, 0, 100, 100))
fmt.Println(m.Bounds()) // (0,0)-(100,100)
fmt.Println(m.At(0, 0).RGBA()) // 0 0 0 0

posted on 2020-05-14 11:40  zwvista  阅读(174)  评论(0编辑  收藏  举报