Go常见错误第15篇:interface使用的常见错误和最佳实践

前言

这是Go常见错误系列的第15篇:interface使用的常见错误和最佳实践。

素材来源于Go布道者,现Docker公司资深工程师Teiva Harsanyi

本文涉及的源代码全部开源在:Go常见错误源代码,欢迎大家关注公众号,及时获取本系列最新更新。

常见错误和最佳实践

interface是Go语言里的核心功能,但是在日常开发中,经常会出现interface被乱用的情况,代码过度抽象,或者抽象不合理,导致代码晦涩难懂。

本文先带大家回顾下interface的重要概念,然后讲解使用interface的常见错误和最佳实践。

interface重要概念回顾

interface里面包含了若干个方法,大家可以理解为一个interface代表了一类群体的共同行为。

结构体要实现interface不需要类似implement的关键字,只要该结构体实现了interface里的所有方法即可。

我们拿Go语言里的io标准库来说明interface的强大之处。io标准库包含了2个interface:

  • io.Reader:表示从某个数据源读数据
  • io.Writer:表示写数据到目标位置,比如写到指定文件或者数据库
Figure 2.3 io.Reader reads from a data source and fills a byte slice, whereas io.Writer writes to a target from a byte slice.

img

io.Reader这个interface里只有一个Read方法:

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

Read reads up to len§ bytes into p. It returns the number of bytes read (0 <= n <= len§) and any error encountered. Even if Read returns n < len§, it may use all of p as scratch space during the call. If some data is available but not len§ bytes, Read conventionally returns what is available instead of waiting for more.

如果某个结构体要实现io.Reader,需要实现Read方法。这个方法要包含以下逻辑:

  • 入参:接受元素类型为byte的slice作为方法的入参。
  • 方法逻辑:把Reader对象里的数据读出来赋值给p。比如Reader对象可能是一个strings.Reader,那调用Read方法就是把string的值赋值给p。
  • 返回值:要么返回读到的字节数,要么返回error。

io.Writer这个interface里只有一个Write方法:

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

Write writes len§ bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len§) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len§. Write must not modify the slice data, even temporarily.

如果某个结构体要实现io.Writer,需要实现Write方法。这个方法要包含以下逻辑:

  • 入参:接受元素类型为byte的slice作为方法的入参。
  • 方法逻辑:把p的值写入到Writer对象。比如Writer对象可能是一个os.File类型,那调用Write方法就是把p的值写入到文件里。
  • 返回值:要么返回写入的字节数,要么返回error。

这2个函数看起来非常抽象,很多Go初级开发者都不太理解,为啥要设计这样2个interface?

试想这样一个场景,假设我们要实现一个函数,功能是拷贝一个文件的内容到另一个文件。

  • 方式1:这个函数用2个*os.Files作为参数,来从一个文件读内容,写入到另一个文件

    func copySourceToDest(source *io.File, dest *io.File) error {
         
        // ...<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值