• go语言之接口一


    在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口

    我们定义了一个File类,并实现有Read()、Write()、Seek()、Close()等方法。设

    想我们有如下接口:

    type IFile interface {

            Read(buf []byte) (n int,err error)

            Write(buf []byte) (n int,err error)

            Seek(off int4,whence int)(pos int64,err error)

            Close() error

    }

    type IReader interface {

            Read(buf []byte) (n int, err error)

    }

    type IWriter interface {

            Write(buf []byte) (n int, err error)

    }

    type ICloser interface {

            Close() error

    }

    尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了

    这些接口,可以进行赋值:

    var file1 IFile = new(File)

    var file2 IReader = new(File)

    var file3 IWriter = new(File)

    var file4 ICloser = new(File)

    接口赋值:

    Go语言中分为如下两种情况的接口赋值

    1 将对象实例赋值给接口

    2 将一个接口赋值给另一个接口

    1 对象实例赋值给接口:

    func (a Integer) Less(b Integer) bool{

            return a < b

    }

    func (a *Integer) Add(b Integer){

            *a+=b

    }

    type LessAdder interface{

            Less(b Integer) bool

            Add(b Integer)

    }

    赋值的方式如下:

    func main(){

            var a Integer = 1

            var LA LessAdder = a

            LA.Less(3)

    }

    运行报错:

    cannot use a (type Integer) as type LessAdder in assignment:

            Integer does not implement LessAdder (Add method has pointer receiver)

    这个错误的原因是因为Add方法的类型是指针的形式,由类型指针接收的方法必须由对象指针表示和传入。正确的传递方法应该是var LA LessAdder =&a。这样Add方法就能够满足了。那Less方法传递的是非指针,这个时候是否会报错呢?答案是不会的。原因在于Go语言可以根据下面的函数

    func (a Integer) Less(b Integer) bool{

            return a < b

    }

    自动生成一个新的Less方法

    func (a *Integer) Less(b Integer) bool{

            return (*a) < b

    }

    类型*Integer就既存在Less()方法,也存在Add()方法,满足LessAdder接口。而

    从另一方面来说,根据

    func (a *Integer) Add(b Integer)

    这个函数无法自动生成以下这个成员方法:

    func (a Integer) Add(b Integer) {

    (&a).Add(b)

    }

    因为(&a).Add()改变的只是函数参数a,对外部实际要操作的对象并无影响,这不符合用

    户的预期。所以,Go语言不会自动为其生成该函数。因此,类型Integer只存在Less()方法,

    缺少Add()方法,不满足LessAdder接口.

    2 将一个接口赋值给另一个接口

    来看一个示例,这是第一个接口:

    package one

    type ReadWriter interface {

    Read(buf []byte) (n int, err error)

    Write(buf []byte) (n int, err error)

    }

    第二个接口位于另一个包中:

    package two

    type IStream interface {

    Write(buf []byte) (n int, err error)

    Read(buf []byte) (n int, err error)

    }

     

    这里我们定义了两个接口,一个叫one.ReadWriter,一个叫two.Istream,两者都定义

    了Read()、Write()方法,只是定义次序相反。one.ReadWriter先定义了Read()再定义了

    Write(),而two.IStream反之。

    在Go语言中,这两个接口实际上并无区别,因为:

    1 任何实现了one.ReadWriter接口的类,均实现了two.IStream;

    2 任何one.ReadWriter接口对象可赋值给two.IStream,反之亦然;

    3 在任何地方使用one.ReadWriter接口与使用two.IStream并无差异。

     

    以下这些代码可编译通过:

    var file1 two.IStream = new(File)

    var file2 one.ReadWriter = file1

    var file3 two.IStream = file2

    接口赋值并不要求两个接口必须等价。如果接口A的方法列表是接口B的方法列表的子集,

    那么接口B可以赋值给接口A。例如,假设我们有Writer接口:

    type Writer interface {

    Write(buf []byte) (n int, err error)

    }

    就可以将上面的one.ReadWriter和two.IStream接口的实例赋值给Writer接口:

    var file1 two.IStream = new(File)

    var file4 Writer = file1

    但是反过来并不成立:

    var file1 Writer = new(File)

    var file5 two.IStream = file1 // 编译不能通过

    这段代码无法编译通过,原因是显然的:file1并没有Read()方法。

  • 相关阅读:
    『Power AI by AI』 PAI-AutoML2.0重磅发布
    基于 K8s 做应用发布的工具那么多, 阿里为啥选择灰姑娘般的 Tekton ?
    编码方法论,赋能你我他
    开发部署效率提升 12 倍,这款应用托管服务让云上运维更简单
    全景还原报错现场 | 应用实时监控 ARMS 上线用户行为回溯功能
    告别诊断烦恼 | 应用实时监控 ARMS 上线智能和实时诊断功能
    阿里云CDN上线 WAF,一站式提供分发+安全能力
    RDS for PostgreSQL 云盘加密功能使用方法
    MySQL8.0.17
    2370 小机房的树
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/9546347.html
Copyright © 2020-2023  润新知