您的位置:首页 > 编程语言

golang语言渐入佳境[19]-从go源代码读懂interface接口

2018-12-05 19:48 821 查看

go源代码中的接口

http库中,get方法:

1
func Get(url string) (resp *Response, err error)

Response:

12
3
4
5
6
7
8
9
type Response struct {
       Status     string // e.g. "200 OK"
       StatusCode int    // e.g. 200
       Proto      string // e.g. "HTTP/1.0"
       ProtoMajor int    // e.g. 1        ProtoMinor int    // e.g. 0
       Header Header

       Body io.ReadCloser

io.ReadCloser:

12
3
4
type ReadCloser interface {
        Reader
        Closer
}

Reader:

12
3
type Reader interface {
        Read(p []byte) (n int, err error)
}

Closer:

12
3
type Closer interface {
        Close() error
}

不管是读取文件、网络等操作,都实现了相同的Reader接口。当传递[]byte进去,会将读取到的byte放置进去。成功会返回成功的个数。

12
3
4
5
6
7
8
9
10
1112
13
14
15
16
17
18
19
20
21
package main

import (
	"net/http"
	"fmt"
	"os"
)

func main(){
	resp,err := http.Get("http://tmall.com")

	if err !=nil{
		fmt.Println("Error:",err)
		os.Exit(1)
	}
  //设置大一点,read方法不会自动的扩容。
	bs:=make([]byte,99999)
  //read函数将读取到的数据放入到bs中。
	resp.Body.Read(bs)
	fmt.Println(string(bs))
}

write接口

12
3
type Writer interface {
        Write(p []byte) (n int, err error)
}

io.opy

12
3
4
5
6
7
8
9
10
1112
13
14
15
16
17
18
19
20
package main

import (
	"net/http"
	"fmt"
	"os"
	"io"
)

func main(){
	resp,err := http.Get("http://tmall.com")

	if err !=nil{
		fmt.Println("Error:",err)
		os.Exit(1)
	}

	//读取resp.Body中的信息,写到os.Stdout中。os.Stdout实现了write接口,resp.Body实现了read接口。
	io.Copy(os.Stdout,resp.Body)
}

io.copy源码

12
3
4
5
6
7
8
9
10
1112
13
14
15
16
17
18
19
20
2122
23
24
25
26
27
28
29
30
3132
33
34
35
36
37
38
39
40
4142
43
44
45
46
47
48
49
50
5152
53
54
55
56
57
58
func Copy(dst Writer, src Reader) (written int64, err error) {
return copyBuffer(dst, src, nil)
}

---------
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
if buf != nil && len(buf) == 0 {
panic("empty buffer in io.CopyBuffer")
}
return copyBuffer(dst, src, buf)
}
---------
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
size := 32 * 1024  
if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
if l.N < 1 {
size = 1 } else {
size = int(l.N)
}
}
if buf == nil {
buf = make([]byte, size)//分配
}
for {   //疯狂读取并写入
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = ErrShortWrite
break
}
}
if er != nil {
if er != EOF {
err = er
}
break
}
}
return written, err
}

自定义Writer函数

12
3
4
5
6
7
8
9
10
1112
13
14
15
16
17
18
19
20
2122
23
24
25
26
27
28
29
30
31
package main

import (
	"net/http"
	"fmt"
	"os"
	"io"
)


type logWriter struct{}

func main(){
	resp,err := http.Get("http://tmall.com")

	if err !=nil{
		fmt.Println("Error:",err)
		os.Exit(1)
	}

	lw:= logWriter{}

  //读取resp.Body中的信息,写到os.Stdout中。os.Stdout实现了write接口,resp.Body实现了read接口。
	io.Copy(lw,resp.Body)
}

func (logWriter) Write(bs []byte)(int,error){
	fmt.Println(string(bs))
	fmt.Println("Just wrote this many bytes",len(bs))
	return len(bs),nil
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  区块链 go