Go语言接口在实际应用中的一些思维过程 (语言转型同学可看)

cheney2022 · · 883 次点击 · · 开始浏览    

在一个基于缓冲和非缓冲输出的代码测试过程中, 一些接口类型使用时的思考过程(超详细) ``` package main import ( "bufio" "fmt" "os" ) func main() { // io包中接口的概念 fmt.Fprintf(os.Stdout, "%s\n", "这些文字不经过缓冲") // 通过bufio标准库创建一个io.Writer接口类型变量的缓冲 /** * bufio中的Writer类型(结构体) 实现了io.Writer接口对象提供的缓冲. * 如果在向一个Writer类型值写入时遇到了错误, 该对象不再接受任何数据,且所有写操作都会返回该错误 * 再说数据都写入后, 调用者有义务调用Flush方法以保证所有的数据都交给了下层的io.Writer * * bufio.NewWriter() 返回了一个bufio.Writer的指针 * 调用逻辑: * bufio.NewWriter 需要传入一个实现io.Writer接口的变量 * 此时传入的值是 os.Stdout * >os.Stdout是什么 它是os.File的指针, 溯源代码可以发现os.Stdout 的文件描述符是1 即输出他的变量构建通过os中的NewFile创建了一个&File * >那此时我们想到传参其实是需要是实现io.Writer类型的变量, os.File是否实现了io.Writer 我们看一看 * >回想go的接口实现, 当一个变量被要求是指定接口类型时, 此变量类型上一定定义了接口中要求的方法, 此例中, io.Writer要求实现了Write方法签名, io.Write方法参数要求一个byte切片类型并返回一个整型和错误 * >回到第一步分析, os.Stdout是一个os.File的指针, 那么os.File类型的指针变量是否实现了io.Writer接口?(是的, 移步查看os中结构体File上定义的方法, 这里对于面向对象转来的同学不好理解, 接口在哪里实现) * >针对上一行问题引入io标准库和os标准库的概念: * >io库提供了对I/O原语的基本接口, 可以理解为将这些原语的现有实现(如os库中的原语) 包装到抽象功能的公共接口中, 以及一些其他的相关原语 * >os库为操作系统功能提供了一个独立于平台的接口. 设计类似于Unix, 进款错误处理类似于Go; 失败的调用返回错误类型的值,而不是错误号.os接口旨在在所有操作系统中保持统一的接口形态.通常不可用的功能出现在系统特定的包系统调用中 * > OK, 了解完以上两个概念以后, 我们并没有看到问题得到解释 * > 那我们只能回到代码寻找一些证据, 那么我们可以找到io库中的Writer是一个接口,此接口要求变量是一个实现了Write方法的类型 * > os.File类型上定义了Write方法此方法的签名结构和io.Writer要求的结构一致, 回想我们对Go语言接口实现的认知, Go语言的接口是被隐式实现的, 即只要实现了接口中的方法就实现了改接口 * > 综上, 解释了为什么os.Stdout 是 io.Writer 接口类型 (有时候直观上看不到继承, 尤其是从面向对象来的同学可能会很诧异这个类型是怎么被实现的, 这里就完美的做一个思维上的理解) */ buf := bufio.NewWriter(os.Stdout) fmt.Fprintf(buf, "%s\n", "这些文字在缓冲区中") // 此时如果不调用buf.Flush 则所有数据仍然在缓冲中, 并未将数据刷给下层的io.Writer buf.Flush() // Flush方法将缓冲区中的数据写入下层的io.Writer接口 } ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

883 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传