第四章 面向接口
接口的定义
接口由使用者定义
type Retiever
interface {
Get( url
string ) string
}
func download( retriever Retiever
) {
return retriever
.Get("http://www.baidu.com")
}
接口的实现是隐式的只要实现接口里的方法
接口变量里有什么
func main() {
var r Retriever
}
package mock
type Retriever
struct {
Contents
string
}
func (r
*Retriever
) Get(url
string) string {
return r
.Contents
}
package real
type Retriever
struct {
UserAgent
string
TimeOut time
.Duration
}
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
)
}
实现者的类型 和 实现者的指针接口变量自带指针接口变量才用值传递, 几乎不需要使用接口的指针
查看接口变量
表示任何类型:interface{}Type Assertion
var r Retriever
if mockRetriever
, ok
:= r
.(*mock
.Retriever
); ok
{
fmt
.Println(mockRetriever
.Contents
)
} else {
fmt
.Println("r is not a mock retriever")
}
Type Switch
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()
}
var r Retriever
mockRetriever
:= mock
.Retriever
{Contents
: "this is a fake imooc.com"}
r
= &mockRetriever
inspect(r
)
r
= &real.Retriever
{
UserAgent
: "Mozilla/5.0",
TimeOut
: time
.Minute
,
}
inspect(r
)
接口的组合
type Poster
interface {
Post(url
string,
form
map[string]string) string
}
const url
= "http://www.imooc.com"
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 imooc.com",
})
return s
.Get(url
)
}
特殊接口
Stringer
func (r
*Retriever
) String() string {
return fmt
.Sprintf(
"Retriever: {Contents=%s}", r
.Contents
)
}
Reader/Writer
func printFileContents(reader io
.Reader
) {
scanner
:= bufio
.NewScanner(reader
)
for scanner
.Scan() {
fmt
.Println(scanner
.Text())
}
}