当前位置:   article > 正文

golang Interface类型详解_golang interface类型

golang interface类型

   简单的说,接口就是一组方法签名的集合。我们使用一个接口来识别一个对象能够进行的操作。

  1. type Human struct {
  2. name string
  3. age int
  4. phone string
  5. }
  6. type Student struct {
  7. Human //an anonymous field of type Human
  8. school string
  9. loan float32
  10. }
  11. type Employee struct {
  12. Human //an anonymous field of type Human
  13. company string
  14. money float32
  15. }
  16. // A human likes to stay... err... *say* hi
  17. func (h *Human) SayHi() {
  18. fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
  19. }
  20. // A human can sing a song, preferrably to a familiar tune!
  21. func (h *Human) Sing(lyrics string) {
  22. fmt.Println("La la, la la la, la la la la la...", lyrics)
  23. }
  24. // A Human man likes to guzzle his beer!
  25. func (h *Human) Guzzle(beerStein string) {
  26. fmt.Println("Guzzle Guzzle Guzzle...", beerStein)
  27. }
  28. // Employee's method for saying hi overrides a normal Human's one
  29. func (e *Employee) SayHi() {
  30. fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
  31. e.company, e.phone) //Yes you can split into 2 lines here.
  32. }
  33. // A Student borrows some money
  34. func (s *Student) BorrowMoney(amount float32) {
  35. loan += amount // (again and again and...)
  36. }
  37. // An Employee spends some of his salary
  38. func (e *Employee) SpendSalary(amount float32) {
  39. e.money -= amount // More vodka please!!! Get me through the day!
  40. }
  41. // INTERFACES
  42. type Men interface {
  43. SayHi()
  44. Sing(lyrics string)
  45. Guzzle(beerStein string)
  46. }
  47. type YoungChap interface {
  48. SayHi()
  49. Sing(song string)
  50. BorrowMoney(amount float32)
  51. }
  52. type ElderlyGent interface {
  53. SayHi()
  54. Sing(song string)
  55. SpendSalary(amount float32)
  56. }

    一个接口可以被任意数量的类型满足,并且,一个类型可以实现任意数量的接口。最后需要说明的是,每个类型都实现了一个空接口interface{}。

   因为接口也是一种类型,你可以声明一个接口变量,这个变量能够存储任何实现该接口的对象类型。也就是说,如果我们声明了Men类型的接口变量m,那么这个变量就可以存储Student和Employee类型的对象,还有Human类型。这是因为它们都实现了Men接口声明的方法签名。

   如果m能够存储不同数据类型的值,我们可以轻松实现一个Men切片,该切片包含不同的数据类型的实例。

  1. package main
  2. import "fmt"
  3. type Human struct {
  4. name string
  5. age int
  6. phone string
  7. }
  8. type Student struct {
  9. Human //an anonymous field of type Human
  10. school string
  11. loan float32
  12. }
  13. type Employee struct {
  14. Human //an anonymous field of type Human
  15. company string
  16. money float32
  17. }
  18. //A human method to say hi
  19. func (h Human) SayHi() {
  20. fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
  21. }
  22. //A human can sing a song
  23. func (h Human) Sing(lyrics string) {
  24. fmt.Println("La la la la...", lyrics)
  25. }
  26. //Employee's method overrides Human's one
  27. func (e Employee) SayHi() {
  28. fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
  29. e.company, e.phone) //Yes you can split into 2 lines here.
  30. }
  31. // Interface Men is implemented by Human, Student and Employee
  32. // because it contains methods implemented by them.
  33. type Men interface {
  34. SayHi()
  35. Sing(lyrics string)
  36. }
  37. func main() {
  38. mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}
  39. paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}
  40. sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}
  41. Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000}
  42. //a variable of the interface type Men
  43. var i Men
  44. //i can store a Student
  45. i = mike
  46. fmt.Println("This is Mike, a Student:")
  47. i.SayHi()
  48. i.Sing("November rain")
  49. //i can store an Employee too
  50. i = Tom
  51. fmt.Println("This is Tom, an Employee:")
  52. i.SayHi()
  53. i.Sing("Born to be wild")
  54. //a slice of Men
  55. fmt.Println("Let's use a slice of Men and see what happens")
  56. x := make([]Men, 3)
  57. //These elements are of different types that satisfy the Men interface
  58. x[0], x[1], x[2] = paul, sam, mike
  59. for _, value := range x{
  60. value.SayHi()
  61. }
  62. }

   输出结果是:

  1. This is Mike, a Student:
  2. Hi, I am Mike you can call me on 222-222-XXX
  3. La la la la... November rain
  4. This is Tom, an Employee:
  5. Hi, I am Sam, I work at Things Ltd.. Call me on 444-222-XXX
  6. La la la la... Born to be wild
  7. Let’s use a slice of Men and see what happens
  8. Hi, I am Paul you can call me on 111-222-XXX
  9. Hi, I am Sam, I work at Golang Inc.. Call me on 444-222-XXX
  10. Hi, I am Mike you can call me on 222-222-XXX

   接口类型是一组抽象的方法集,它本身不实现方法或精确描述数据结构和方法的实现方式。值得注意的是这些数据类型没有提及任何的关于接口的信息,方法签名的实现部分也没有包含给定的接口类型的信息。

   同样的,一个接口类型也不会关心到底是什么数据类型实现了它自身。接口类型的本质就是如果一个数据类型实现了自身的方法集,那么该接口类型变量就能够引用该数据类型的值。

   空接口类型interface{}一个方法签名也不包含,所以所有的数据类型都实现了该方法。空接口类型在描述一个对象实例的行为上力不从心,但是当我们需要存储任意数据类型的实例的时候,空接口类型的使用使得我们得心应手。

   如果一个函数的参数包括空接口类型interface{},实际上函数是在说“兄弟,我接受任何数据”。如果一个函数返回一个空接口类型,那么函数再说“我也不确定返回什么,你只要知道我一定返回一个值就好了”。

 

参考:

https://www.yuque.com/docs/share/d25a5102-1a53-4640-b26d-5ed23c4977c1

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/907924
推荐阅读
相关标签
  

闽ICP备14008679号