概述

  • 使用者定义接口
  • 接口中包含类型和值。可以是真实的值也可以是指针,如果是真实值的化是拷贝
  1. switch v := r.(type) 可以判断接口中的类型
  2. (Type assertion) mockRetriever, ok := r.(*mock.Retriever)
  • 接口变量自带指针
  • 接口变量同样采用值传递,几乎不需要使用接口的指针
  • 指针接收者实现只能以指针方式使用,值接收者都可
  • 任何类型:interface{}
  • 任何类型的值强制转换 head.(int)

go 基础学习 接口 - 图1

代码

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "golearn/retriever/mock"
  6. "golearn/retriever/real"
  7. )
  8. type Retriever interface {
  9. Get(url string) string
  10. }
  11. type Poster interface {
  12. Post(url string,
  13. form map[string]string) string
  14. }
  15. const url = "http://www.baidu.com"
  16. func download(r Retriever) string {
  17. return r.Get(url)
  18. }
  19. func post(poster Poster) {
  20. poster.Post(url,
  21. map[string]string{
  22. "name": "ccmouse",
  23. "course": "golang",
  24. })
  25. }
  26. type RetrieverPoster interface {
  27. Retriever
  28. Poster
  29. }
  30. func session(s RetrieverPoster) string {
  31. s.Post(url, map[string]string{
  32. "contents": "another faked ctoedu.com",
  33. })
  34. return s.Get(url)
  35. }
  36. func main() {
  37. var r Retriever
  38. mockRetriever := mock.Retriever{
  39. Contents: "this is a fake ctoedu.com"}
  40. r = &mockRetriever
  41. inspect(r)
  42. r = &real.Retriever{
  43. UserAgent: "Mozilla/5.0",
  44. TimeOut: time.Minute,
  45. }
  46. inspect(r)
  47. // Type assertion
  48. if mockRetriever, ok := r.(*mock.Retriever); ok {
  49. fmt.Println(mockRetriever.Contents)
  50. } else {
  51. fmt.Println("r is not a mock retriever")
  52. }
  53. fmt.Println(
  54. "Try a session with mockRetriever")
  55. fmt.Println(session(&mockRetriever))
  56. }
  57. func inspect(r Retriever) {
  58. fmt.Println("Inspecting", r)
  59. fmt.Printf(" > Type:%T Value:%v\n", r, r)
  60. fmt.Print(" > Type switch: ")
  61. switch v := r.(type) {
  62. case *mock.Retriever:
  63. fmt.Println("Contents:", v.Contents)
  64. case *real.Retriever:
  65. fmt.Println("UserAgent:", v.UserAgent)
  66. }
  67. fmt.Println()
  68. }
  1. package mock
  2. import "fmt"
  3. type Retriever struct {
  4. Contents string
  5. }
  6. func (r *Retriever) String() string {
  7. return fmt.Sprintf(
  8. "Retriever: {Contents=%s}", r.Contents)
  9. }
  10. func (r *Retriever) Post(url string,
  11. form map[string]string) string {
  12. r.Contents = form["contents"]
  13. return "ok"
  14. }
  15. func (r *Retriever) Get(url string) string {
  16. return r.Contents
  17. }
  1. package real
  2. import (
  3. "net/http"
  4. "net/http/httputil"
  5. "time"
  6. )
  7. type Retriever struct {
  8. UserAgent string
  9. TimeOut time.Duration
  10. }
  11. func (r *Retriever) Get(url string) string {
  12. resp, err := http.Get(url)
  13. if err != nil {
  14. panic(err)
  15. }
  16. result, err := httputil.DumpResponse(
  17. resp, true)
  18. resp.Body.Close()
  19. if err != nil {
  20. panic(err)
  21. }
  22. return string(result)
  23. }

image.jpeg