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
*/