A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wuqiong 金牌黑马   /  2018-7-20 10:00  /  1455 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

概述
  • 使用者定义接口

  • 接口中包含类型和值。可以是真实的值也可以是指针,如果是真实值的化是拷贝

    • switch v := r.(type) 可以判断接口中的类型

    • (Type assertion) mockRetriever, ok := r.(*mock.Retriever)

    • 接口变量自带指针

    • 接口变量同样采用值传递,几乎不需要使用接口的指针

    • 指针接收者实现只能以指针方式使用,值接收者都可

    • 任何类型:interface{}

    • 任何类型的值强制转换 head.(int)



代码package main

import (
        "fmt"

        "time"

        "golearn/retriever/mock"
        "golearn/retriever/real"
)

type Retriever interface {
        Get(url string) string
}

type Poster interface {
        Post(url string,
                form map[string]string) string
}

const url = "http://www.baidu.com"

func download(r Retriever) string {
        return r.Get(url)
}

func post(poster Poster) {
        poster.Post(url,
                map[string]string{
                        "name":   "ccmouse",
                        "course": "golang",
                })
}

type RetrieverPoster interface {
        Retriever
        Poster
}

func session(s RetrieverPoster) string {
        s.Post(url, map[string]string{
                "contents": "another faked ctoedu.com",
        })
        return s.Get(url)
}

func main() {
        var r Retriever

        mockRetriever := mock.Retriever{
                Contents: "this is a fake ctoedu.com"}
        r = &mockRetriever
        inspect(r)

        r = &real.Retriever{
                UserAgent: "Mozilla/5.0",
                TimeOut:   time.Minute,
        }
        inspect(r)

        // Type assertion
        if mockRetriever, ok := r.(*mock.Retriever); ok {
                fmt.Println(mockRetriever.Contents)
        } else {
                fmt.Println("r is not a mock retriever")
        }

        fmt.Println(
                "Try a session with mockRetriever")
        fmt.Println(session(&mockRetriever))
}

func inspect(r Retriever) {
        fmt.Println("Inspecting", r)
        fmt.Printf(" > Type:%T Value:%v\n", r, r)
        fmt.Print(" > Type switch: ")
        switch v := r.(type) {
        case *mock.Retriever:
                fmt.Println("Contents:", v.Contents)
        case *real.Retriever:
                fmt.Println("UserAgent:", v.UserAgent)
        }
        fmt.Println()
}

package mock

import "fmt"

type Retriever struct {
        Contents string
}

func (r *Retriever) String() string {
        return fmt.Sprintf(
                "Retriever: {Contents=%s}", r.Contents)
}

func (r *Retriever) Post(url string,
        form map[string]string) string {
        r.Contents = form["contents"]
        return "ok"
}

func (r *Retriever) Get(url string) string {
        return r.Contents
}


5 个回复

倒序浏览
优秀,奈斯
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马