zhcn 编程语言 Golang Golang 函数 非公開: Go语言类型与接口的关系

Go语言类型与接口的关系

Go语言中类型和接口之间存在一对多和多对一的关系。为了帮助读者理解复杂环境下接口和类型之间的实现关系,下面列出了这些常见概念。

一个类型可以实现多个接口

一个类型可以同时实现多个接口,但是这些接口是相互独立的,并且不知道彼此的实现。

网络上的两个程序通过双向通信连接交换数据,连接的一端称为套接字。套接字与文件一样,可以同时读取和写入数据。因此,在开发中,文件和套接字的读写功能被抽象为一个独立的读取器概念。

套接字和文件一样,需要在使用后释放资源。

使用接口来描述可以写入数据和必须关闭的套接字的特征。请参阅下面的代码。

 type Socket struct {
}

func (s *Socket) Write(p []byte) (n int, err error) {
    return 0, nil
}

func (s *Socket) Close() error {
    return nil
} 

Socket 结构的 Write() 方法实现了 io.Writer 接口。

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

同时Socket结构体还实现了io.Closer接口。

 type Closer interface {
    Close() error
} 

通过使用Socket实现的Writer接口的代码,Writer接口的实现者不需要知道它是否具有Closer接口的特性。同样,使用 Closer 接口的代码并不知道 Socket 实现了 Writer 接口,如下图所示。

下面是在代码中使用Socket结构实现的Writer和Closer接口的代码。

 // io.Writerを利用するコードで、Socketとio.Closerの存在を知らない
func usingWriter(writer io.Writer){
    writer.Write(nil)
}

// io.Closerを利用するコードで、Socketとio.Writerの存在を知らない
func usingCloser(closer io.Closer) {
    closer.Close()
}

func main() {

    // Socketのインスタンス化
    s := new(Socket)

    usingWriter(s)

    usingCloser(s)
} 

usingWriter() 和 usingCloser() 完全独立,不知道彼此的存在。我也不知道我使用的接口是Socket实现的。

多种类型可以实现同一个接口

接口的方法不一定必须由类型完全实现;接口的方法可以通过在该类型中嵌入其他类型或结构来实现。也就是说,用户并不关心特定接口的方法是完全由一种类型实现还是由嵌入并组合实现的多种结构实现。

Service接口定义了两个方法:启动服务的方法(Start())和输出日志的方法(Log())。使用GameService结构体来实现Service。 GameService本身的结构体只能实现Start()方法,而Service接口的Log()方法是由一个可以输出日志的logger实现的,所以需要对GameService进行封装或者重新实现一遍。因此,选择在GameService中嵌入Logger将帮助您避免最大程度的代码冗余并简化您的代码结构。详细实现流程如下:

 // 1つのサービスは、開始およびログの書き込み機能を備える必要があります
type Service interface {
    Start() // サービスを開始します
    Log(string) // ログを出力します
}

// ロガー
type Logger struct {
}

// ServiceのLog()メソッドを実装する
func (g *Logger) Log(l string) {

}

// ゲームサービス
type GameService struct {
    Logger // ロガーを埋め込む
}

// ServiceのStart()メソッドを実装する
func (g *GameService) Start() {
} 

代码说明如下:

  • 第2行定义了服务接口,服务必须实现Start()和log方法。
  • 第8行定义了一个可以输出日志的logger结构体。
  • 第12行,在Logger中添加Log()方法,同时实现Service的Log()方法。
  • 第 17 行定义了 GameService 结构。
  • 第18行在GameService中嵌入Logger记录器,实现日志功能。
  • 第 22 行,GameService 的 Start() 方法实现了 Service 的 Start() 方法。

此时,实例化 GameService 并将该实例分配给您的服务。这是代码:

 var s Service = new(GameService)
s.Start()
s.Log(“hello”) 

s 允许 Start() 和 Log() 方法。 Start()方法由GameService实现,Log()方法由Logger实现。

通俗易懂地讲解Go语言类型与接口的关系!您必须观看的 2 个最佳视频

一緒に学ぶGo言語入門 ~その9:メソッドとインターフェース(前編)~
https://www.youtube.com/watch?v=ntLdZ_qyqTM&pp=ygU8IEdv6KiA6Kqe44Gu56iu6aGe44Go44Kk44Oz44K_44O844OV44Kn44O844K544Gu6Zai5L-CJmhsPUpB
Go言語で何ができるの?どこで使われてる?現役エンジニアが解説
https://www.youtube.com/watch?v=ZtDMTl_s30s&pp=ygU8IEdv6KiA6Kqe44Gu56iu6aGe44Go44Kk44Oz44K_44O844OV44Kn44O844K544Gu6Zai5L-CJmhsPUpB
Go语言中类型和接口之间存在一对多和多对一的关系。为了帮助读者理解复杂环境下接口和类型之间的实现关系,下面列出了这些常见概念。

一个类型可以实现多个接口

一个类型可以同时实现多个接口,但是这些接口是相互独立的,并且不知道彼此的实现。

网络上的两个程序通过双向通信连接交换数据,连接的一端称为套接字。套接字与文件一样,可以同时读取和写入数据。因此,在开发中,文件和套接字的读写功能被抽象为一个独立的读取器概念。

套接字和文件一样,需要在使用后释放资源。

使用接口来描述可以写入数据和必须关闭的套接字的特征。请参阅下面的代码。

 type Socket struct {
}

func (s *Socket) Write(p []byte) (n int, err error) {
    return 0, nil
}

func (s *Socket) Close() error {
    return nil
} 

Socket 结构的 Write() 方法实现了 io.Writer 接口。

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

同时Socket结构体还实现了io.Closer接口。

 type Closer interface {
    Close() error
} 

通过使用Socket实现的Writer接口的代码,Writer接口的实现者不需要知道它是否具有Closer接口的特性。同样,使用 Closer 接口的代码并不知道 Socket 实现了 Writer 接口,如下图所示。

下面是在代码中使用Socket结构实现的Writer和Closer接口的代码。

 // io.Writerを利用するコードで、Socketとio.Closerの存在を知らない
func usingWriter(writer io.Writer){
    writer.Write(nil)
}

// io.Closerを利用するコードで、Socketとio.Writerの存在を知らない
func usingCloser(closer io.Closer) {
    closer.Close()
}

func main() {

    // Socketのインスタンス化
    s := new(Socket)

    usingWriter(s)

    usingCloser(s)
} 

usingWriter() 和 usingCloser() 完全独立,不知道彼此的存在。我也不知道我使用的接口是Socket实现的。

多种类型可以实现同一个接口

接口的方法不一定必须由类型完全实现;接口的方法可以通过在该类型中嵌入其他类型或结构来实现。也就是说,用户并不关心特定接口的方法是完全由一种类型实现还是由嵌入并组合实现的多种结构实现。

Service接口定义了两个方法:启动服务的方法(Start())和输出日志的方法(Log())。使用GameService结构体来实现Service。 GameService本身的结构体只能实现Start()方法,而Service接口的Log()方法是由一个可以输出日志的logger实现的,所以需要对GameService进行封装或者重新实现一遍。因此,选择在GameService中嵌入Logger将帮助您避免最大程度的代码冗余并简化您的代码结构。详细实现流程如下:

 // 1つのサービスは、開始およびログの書き込み機能を備える必要があります
type Service interface {
    Start() // サービスを開始します
    Log(string) // ログを出力します
}

// ロガー
type Logger struct {
}

// ServiceのLog()メソッドを実装する
func (g *Logger) Log(l string) {

}

// ゲームサービス
type GameService struct {
    Logger // ロガーを埋め込む
}

// ServiceのStart()メソッドを実装する
func (g *GameService) Start() {
} 

代码说明如下:

  • 第2行定义了服务接口,服务必须实现Start()和log方法。
  • 第8行定义了一个可以输出日志的logger结构体。
  • 第12行,在Logger中添加Log()方法,同时实现Service的Log()方法。
  • 第 17 行定义了 GameService 结构。
  • 第18行在GameService中嵌入Logger记录器,实现日志功能。
  • 第 22 行,GameService 的 Start() 方法实现了 Service 的 Start() 方法。

此时,实例化 GameService 并将该实例分配给您的服务。这是代码:

 var s Service = new(GameService)
s.Start()
s.Log(“hello”) 

s 允许 Start() 和 Log() 方法。 Start()方法由GameService实现,Log()方法由Logger实现。

通俗易懂地讲解Go语言类型与接口的关系!您必须观看的 2 个最佳视频

一緒に学ぶGo言語入門 ~その9:メソッドとインターフェース(前編)~
https://www.youtube.com/watch?v=ntLdZ_qyqTM&pp=ygU8IEdv6KiA6Kqe44Gu56iu6aGe44Go44Kk44Oz44K_44O844OV44Kn44O844K544Gu6Zai5L-CJmhsPUpB
Go言語で何ができるの?どこで使われてる?現役エンジニアが解説
https://www.youtube.com/watch?v=ZtDMTl_s30s&pp=ygU8IEdv6KiA6Kqe44Gu56iu6aGe44Go44Kk44Oz44K_44O844OV44Kn44O844K544Gu6Zai5L-CJmhsPUpB