go基礎筆記----面向接口

mock

package mock

import "fmt"

// Retriever 1
type Retriever struct {
	Contents string
}

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

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

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

real

package real

import (
	"net/http"
	"net/http/httputil"
	"time"
)

// Retriever 真實
type Retriever struct {
	UserAgent string
	TimeOut   time.Duration
}

// Get real
func (r *Retriever) Get(url string) string {
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}

	result, err := httputil.DumpResponse(resp, true)
	resp.Body.Close()
	if err != nil {
		panic(err)
	}
	return string(result)
}

main

package main

import (
	"fmt"
	"io"
	"time"

	"./mock"
	"./real"
)

/*
	duck typing
	1.描述事物的外部行爲而非內部結構,從使用者的角度來看問題
	2.嚴格說go屬於結構化類型系統,類似duck typing

	golang接口
	1.interface由使用者定義

*/

// Retriever 實現者
type Retriever interface {
	Get(url string) string
}

// Poster 接口的組合
type Poster interface {
	Post(url string, form map[string]string) string
}

func download(r Retriever) string {
	return r.Get("http://www.imooc.com")
}

func post(poster Poster) {
	poster.Post("http://www.imooc.com",
		map[string]string{
			"name":   "lmf",
			"course": "golang",
		})
}

// RetrieverPoster 將Retriever與Poster 組合使用
type RetrieverPoster interface {
	Retriever
	Poster
}

const url = "http://imooc.com"

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

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

func printFileContents(read io.Reader) {

}

/*
	go接口變量{
		實現者類型,
		實現者的指針 -> 實現者 或者 實現者的值
	}

	接口變量自帶指針
	接口變量同樣使用值傳遞,幾乎不需要使用接口的指針
	指針接收者實現只能以指針方式使用,值接收者都可
	便是任何類型:interface{}
*/

func main() {

	var r Retriever
	retriever := &mock.Retriever{Contents: "this is fake imooc.com"}
	r = retriever
	inspect(r)

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

	// type assertion
	if mockRetrieve, ok := r.(*mock.Retriever); ok {
		fmt.Println(mockRetrieve.Contents)

	} else {
		fmt.Println("not mock retriever")
	}

	// fmt.Println(download(r))
	fmt.Println("try a session")
	fmt.Println(session(retriever))
}

/*
	go語言標準的接口
	1.stringer 加一個string方法就可以結構化string
	2.io.Reader 不一定是文件
	3.io.Writer
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章