实践一:

需求:

给Phone结构体增加一个特有方法 call() ,当Usb接口接收的是 Phone 变量的时候,还需要调用 call() 方法
image.png

代码

  1. // 该案例展示 多态数组 类型断言
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. // 定义 Usb 接口, 有两个方法(行为)
  7. type Usb interface {
  8. start()
  9. stop()
  10. }
  11. // 定义 Phone 结构体, 并实现 start, stop 方法
  12. type Phone struct {
  13. Name string
  14. }
  15. // 值接收者
  16. // Phone 类型实现了 Usb 接口 (就是实现了 Usb 接口的所有方法)
  17. func (phone Phone) start() {
  18. fmt.Printf("%v开始--- \n", phone.Name)
  19. }
  20. func (phone Phone) stop() {
  21. fmt.Printf("%v停止--- \n", phone.Name)
  22. }
  23. // Phone 结构体特有方法
  24. func (phone Phone) call() {
  25. fmt.Printf("%v 手机打电话--- \n", phone.Name)
  26. }
  27. // 定义 Camera 结构体, 并实现 start, stop 方法
  28. type Camera struct {
  29. Name string
  30. }
  31. // 指针接收者
  32. // Camera 类型实现了 Usb 接口 (就是实现了 Usb 接口的所有方法)
  33. func (camera Camera) start() {
  34. fmt.Printf("%v开始--- \n", camera.Name)
  35. }
  36. func (camera Camera) stop() {
  37. fmt.Printf("%v停止--- \n", camera.Name)
  38. }
  39. // 定义 Computer 结构体, 并实现 Working 方法
  40. type Computer struct {
  41. }
  42. // 编写 Working 方法,接收一个 Usb 接口类型的变量,
  43. // 只要一个类型实现了某个接口,那么所有使用这个接口的地方,都支持这种类型的值
  44. // (比如: 实参 phone, camera, 都是 Usb 类型来接收, 这就是多态)
  45. func (computer *Computer) Working(usb Usb) {
  46. usb.start()
  47. // type Usb has no field or method call
  48. // usb.call() // err
  49. // 类型断言 调用 Phone.call()
  50. // 如果 usb 是指向 Phone 类型的变量,就把 usb 转化成 Phone 类型,并调用 Phone.call()
  51. if phone, ok := usb.(Phone); ok {
  52. phone.call()
  53. }
  54. usb.stop()
  55. }
  56. func main() {
  57. // 定义 Usb 接口数组
  58. var usbArr [3]Usb
  59. fmt.Println("usbArr = ", usbArr) // [<nil> <nil> <nil>]
  60. /*
  61. 以下,接口类型的数组,存放了不同类型的元素(Phone, Camera...)
  62. 这里就体现了多态数组
  63. */
  64. usbArr[0] = Phone{"华为"}
  65. usbArr[1] = Camera{"尼康"}
  66. usbArr[2] = Phone{"苹果"}
  67. fmt.Println("usbArr = ", usbArr) // [{华为} 0xc00004c240 {苹果}]
  68. var computer Computer
  69. for _, v := range usbArr {
  70. fmt.Println()
  71. computer.Working(v)
  72. }
  73. }
  74. /*
  75. usbArr = [<nil> <nil> <nil>]
  76. usbArr = [{华为} {尼康} {苹果}]
  77. 华为开始---
  78. 华为 手机打电话---
  79. 华为停止---
  80. 尼康开始---
  81. 尼康停止---
  82. 苹果开始---
  83. 苹果 手机打电话---
  84. 苹果停止---
  85. */

实践二:

需求:

写一个函数,循环判断传入参数的类型

代码

  1. // 编写函数,判断参数是什么类型
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. // 定义 Student 类型
  7. type Student struct{}
  8. // 可以接收多个不同类型的参数
  9. func JudgeType(items ...interface{}) {
  10. for i, v := range items {
  11. i = i + 1
  12. // 类型断言
  13. switch v.(type) {
  14. case bool:
  15. fmt.Printf("第%v个参数是 bool 类型,值:%v \n", i, v)
  16. case float32:
  17. fmt.Printf("第%v个参数是 float32 类型,值:%v \n", i, v)
  18. case float64:
  19. fmt.Printf("第%v个参数是 float64 类型,值:%v \n", i, v)
  20. case int, int16, int32, int64:
  21. fmt.Printf("第%v个参数是 整数 类型,值:%v \n", i, v)
  22. case string:
  23. fmt.Printf("第%v个参数是 string 类型,值:%v \n", i, v)
  24. case Student:
  25. fmt.Printf("第%v个参数是 Student 类型,值:%v \n", i, v)
  26. case *Student:
  27. fmt.Printf("第%v个参数是 *Student 类型,值:%v \n", i, v)
  28. default:
  29. fmt.Printf("第%v个参数类型不确定,值:%v \n", i, v)
  30. }
  31. }
  32. }
  33. func main() {
  34. var n1 float32 = 1.1
  35. var n2 float64 = 2.1
  36. var name string = "tom"
  37. address := "北京"
  38. n3 := 64
  39. stu1 := Student{}
  40. stu2 := &Student{}
  41. JudgeType(n1, n2, name, address, n3, stu1, stu2)
  42. var a interface{}
  43. var b *interface{}
  44. fmt.Printf("a 类型: %T, 值: %v \n", a, a) // a 类型: <nil>, 值: <nil>
  45. fmt.Printf("b 类型: %T, 值: %v \n", b, b) // b 类型: *interface {}, 值: <nil>
  46. }