优秀的编程知识分享平台

网站首页 > 技术文章 正文

对比着学 Go 语言-基础:从源码学习接口基本特性

nanyue 2024-09-04 10:03:46 技术文章 5 ℃

接口

在使用 type 进行定义时,类型为 interface 的对象叫做接口:

type Writer interface { // 类型为 interface, 是接口
}

接口内部会放置 2 类内容:

  • 接口函数
  • 接口内嵌

接口函数

type Writer interface {
    Write(p []byte) (n int, err error) // 接口函数
}

接口内嵌

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

type ReadWriter interface {
    Reader // 已有接口类型
    Writer 已有接口类型
}

实现接口的条件

唯一的要求是类型 A 要拥有类型 B 需要的所有方法。

var w io.Writer
w = os.Stdout // *os.File 拥有 Writer 方法
w = new(bytes.Buffer) // *bytes.Buffer 拥有 Writer 方法
w = time.Second // 编译错误,time.Duration 缺少 Writer 方法

var rwc io.ReadWriteCloser
rwc = os.Stdout // *os.File 有 Read, Write, Close 方法
rwc = new(bytes.Buffer) // 编译错误,bytes.Buffer 缺少 Close 方法

w = rwc // io.ReadWriteCloser 有 Write 方法
rwc = w // 编译错误,io.Writer 缺少 Close 方法


type IntSet struct {/* ... */}
func (*IntSet) String() string
var _ = IntSet{}.String() // 编译错误,String 需要指针 *IntSet 

这里函数定义的是 *IntSet 进行调用,而实际使用的是 IntSet{} 。

var s IntSet
var _ = s.String() // s 此时就是 IntSet 指针,取它的地址 &s 就能得到 IntSet 类型的 String 方法


var _ fmt.Stringer = &s // *IntSet 有 String 方法,通过
var _ fmt.Stringer = s  // 编译错误,IntSet 缺少 String 方法

接口的特点有 2 个:

  • 隐藏类型 A 原有的方法
  • 任意值赋给空接口类型

隐藏类型 A 原有的方法

os.Stdout.Write([]byte("hello")) // os.Stdout 拥有 Write 方法
os.Stdout.Close() // os.Stdout 拥有 Close 方法

var w io.Writer
w = os.Stdout
w.Write([]byte("hello")) // io.Writer 有 Writer ,通过
w.Close() // 编译错误,因为 io.Writer 中没有 Close 方法,因此将 os.Stdout 的方法也隐藏了

任意值赋给空接口类型

var any interface{}
any = true
any = 12.34
any = "hello"
any = map[string]int{"one":1}
any = new(bytes.Buffer)

实例:

type Artifact interface {
    Title() string
    Creators() []string
    Created() time.Time
}

type Text interface {
    Pages() int
    Words() int
    PageSize() int
}

type Audio interface {
    Stream() (io.ReadCloser, error)
    RunningTime() time.Duration
    Format() string // eg. "MP3", "WAV"
}

type Video interface {
    Stream() (io.ReadCloser, error)
    RunningTime() time.Duration
    Format() string // eg. "MP4", "WMV"
    Resolution() (x, y, int)
}

// 可以将 Audio 和 Video 定义一个 Streamer 接口,代表它们之间相同的部分
type Streamer interface {
    Stream()(io.ReadCloser, error) 
    RunningTime() time.Duration
    Format() string
}

Tags:

最近发表
标签列表