《Interfaces in Go》学习笔记

接口

接口的定义

  1. type Shape interfance {
  2. Area() float64
  3. Perimeter() float64
  4. }
  • interface,structs,methods 可以实现面向对象的特性
  • interface是一系列方法的声明

接口有两个类型

  • static 和 dynamic 类型

尽管接口有static类型,但是接口只有dynamic值
_

接口的零值是nil

  • 当仅仅定义接口的变量,并不给变量赋值
  • 接口的dynamic值和类型都是nil

  • 实现接口

    结构体实现接口意味着结构体的属性方法实现接口定义的所有方法
  1. package main
  2. import "fmt"
  3. type Shape interface{
  4. Area() int
  5. Perimeter() int
  6. }
  7. type Rect struct {
  8. width int
  9. length int
  10. }
  11. func (s Rect) Area() int {
  12. return s.width * s.length
  13. }
  14. func (s Rect) Perimeter() int {
  15. return 2 * (s.width + s.length)
  16. }
  17. func main() {
  18. var r Shape = Rect{ 5.0, 4.0 }
  19. fmt.Println(r.Area())
  20. fmt.Println(r.Perimeter())
  21. }

空接口

若在接口中没有声明方法,则说明该接口是空接口
_
内置fmt包中fmt接收的就是可变参数个数的函数,参数的类型是空接口

  1. func Println(a ...interface{}) (n int, err error)

多接口

结构体可以继承多接口

  1. package main
  2. import "fmt"
  3. type Shape interface {
  4. Area() float64
  5. }
  6. type Object interface {
  7. Volume() float64
  8. }
  9. type Cube struct {
  10. side float64
  11. }
  12. func (c Cube) Area() float64 {
  13. return c.side * c.side
  14. }
  15. func (c Cube) Volume() float64 {
  16. return c.side * 2
  17. }
  18. func main() {
  19. c := Cube{3}
  20. fmt.Println(c.Area())
  21. fmt.Println(c.Volume())
  22. }

类型断言(Type assertion)

上面改的例子, 如果将
c := Cube{3}
改成

c := Cube{3}
var s Shape = c
后,调用 s.Volume() 方法就会出现异常

可以通过 类型声明 的特性改造上面的例子:

  1. func main() {
  2. var s shape = Cube(3)
  3. c := s.(Cube)
  4. fmt.Println(c.Area())
  5. fmt.Println(c.Volume())
  6. }

判断变量是否是混合类型
value, ok := i.(Type)

  • 若ok=false, value是nil

Type Switch

  • i.(type) 用来获取变量的类型
  • i.(type) 用来转换变量的类型, 如i.(string)
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. func explain(i interface{}) {
  7. switch i.(type) {
  8. case string:
  9. fmt.Println("i store string ", strings.ToUpper(i.(string)))
  10. case int:
  11. fmt.Println("i store int ", i.(int))
  12. default:
  13. fmt.Println("i store something other ", i)
  14. }
  15. }
  16. func main() {
  17. explain("Hello world")
  18. explain(53)
  19. }

嵌套的接口

  • 内嵌的接口就想内嵌的结构体一样,如果子接口的方法会自动上升到父接口

  1. package main
  2. type Shape interface {
  3. Area() float64
  4. }
  5. type Object interface {
  6. Volume() float64
  7. }
  8. type Material interface {
  9. Shape
  10. Ojbect
  11. }
  12. func main() {
  13. c := Cube{3}
  14. var m Material = c
  15. var s Shape = c
  16. var o Object = c
  17. }

接口方法的接收者是指针还是普通类型值

  • 如果实现接口的struct接收者是指针
  1. package main
  2. import "fmt"
  3. type Shape interface {
  4. Area() int
  5. Perimeter() int
  6. }
  7. type Rect struct{
  8. length int
  9. width int
  10. }
  11. func (r *Rect) Area() int {
  12. return r.length * r.width
  13. }
  14. func (r Rect) Perimeter() int {
  15. return 2 * (r.length + r.width)
  16. }
  17. func main() {
  18. r := Rect {5, 4}
  19. var s Shape = &r // 由于方法接收者是指针
  20. fmt.Println("Rect area is ", s.Area())
  21. fmt.Println("Rect area is ", s.Perimeter())
  22. }