以io.Writer为例看go中的interface{}

阅读该文后的一些理解

###1 io.Writer接口 io.Writer接口有如下定义

package io    

type Writer interface {
    Write(p []byte) (n int, err error)
}
//根据go中接口的特点,所有实现了Write方法的类型,我们都说它实现了io.Writer接口。  

###2 somepkg.abc类型实现了io.Writer接口

package somepkg

type Abc struct {
    id int
}
func (a *Abc) Write(p []byte) (n int, err error){
    //writing....
    return 1,nil   //模拟返回,n表示写了几个字节,err表示是否有错误
}
//根据go中接口的特点,由于abc类型实现了Write方法,我们就说abc类型实现了io.Writer接口。

###3 io.Writer的应用 通常,我们在使用fmt包的时候是使用Println/Printf/Print方法。其实,在fmt包中还有Fprint序列方法,而且,Print序列方法内部调用的是Fprint序列方法。以Fprintln为例看看方法的定义:

func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

方法的第一个参数是io.Writer,也就是说,任何实现了io.Writer接口的类型实例都可以传递进来;
我们再看看Println方法内部实现:

func Println(a ...interface{}) (n int, err error) {
    return Fprintln(os.Stdout, a...)
}

我们不妨追溯一下os.Stdout

Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")

也就是标准输出.
从这里可以看出

  1. NewFile方法new出来的os.FileWrite方法,那么os.File这个Struct就已经实现了io.Writer接口
  2. 上面的=号说明了os.Stdout就是NewFile方法new出来的,他是os.File
  3. 结合前面的1和2,如果某个方法需要一个io.Writer接口作为参数传入的话,完全可以拿os.Stdout作为一个io.Writer接口来用

再看一遍Fprintln方法的定义:

func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

如果第一个参数传递的是一个os.Stdout,内容便会被输出到标准输出,也就是屏幕上。
如果第一个参数传递的是一个普通文件,内容便会被输出到该文件。
如果第一个参数传递的是bytes.Buffer,那么,内容便输出到了buffer中。

###4 与上面的somepkg结合

package main
import "somepkg"
import "fmt"

func main(){
    a := &somepkg.abc{1}
    i,e :=fmt.Fprintln(a,"hello world")
    fmt.Println(i)  // 1
}

"hello world"会写入到a里,具体是如何写的,调用的是abc里的Write方法 当然目前示例abc里的Write方法根本就没有还没写,只是返回了1和nil,所以后面的1会被打印出来

###5 最后 接口命名一般以“动作+er”,理解为可以怎么怎么样的“人”,比如Writer为可以理解为“会Write的人”
一旦某人(某个Struct)有能力Write了(实现Write方法了),我们就自动的认为他是个“会写的人”,是个Writer

任何实现Write方法的Struct都可以当做io.Writer来传递给相关方法(如Fprintln方法)

抱歉,比较啰嗦,为了以后能看懂

转载于:https://my.oschina.net/u/943306/blog/128326

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值