【问题标题】:How to define an interface using another interface如何使用另一个接口定义一个接口
【发布时间】:2021-08-16 15:44:08
【问题描述】:

在Go中,如何使用另一个接口定义一个接口?

这是一个例子:

package main

import (
    "fmt"
)

// Interfaces
type Message interface {
    Read() string
}

type MessageReader interface {
    ReceiveMessages([]Message)
}

// Structs
type SQSMessage struct {
    Content string
}

type SQSMessageReader struct {
    Name string
}

// Implements
func (reader *SQSMessageReader) ReceiveMessages([]SQSMessage) {
}

func (msg *SQSMessage) Read() string {
    return msg.Content
}

// A function needs a reader interface
func FuncNeedsReader(MessageReader) {
    fmt.Println("get reader")
}

func main() {
    var reader SQSMessageReader
    FuncNeedsReader(reader)
}

我收到错误:

./prog.go:40:17: cannot use reader (type SQSMessageReader) as type MessageReader in argument to FuncNeedsReader:
    SQSMessageReader does not implement MessageReader (wrong type for ReceiveMessages method)
        have ReceiveMessages([]SQSMessage)
        want ReceiveMessages([]Message)

有谁知道这个设计是否与 Go 的设计冲突?

我知道我们有“接受接口,返回结构” 所以我也尝试了https://play.golang.org/p/qdGaKRYAqw7,但仍然失败并出现类似错误。

【问题讨论】:

  • 注意错误信息。接口类型仍然是不同的类型,它们的使用对类型等价没有任何影响(因此不满足错误中的“拥有”和“想要”)。本质上,接口对类型系统的唯一影响是它创建了一个新的assignability rule。类型等价或深度转换没有更多的魔力。

标签: go


【解决方案1】:

我发现这里有两个问题。

第一:

您已将MessageReader 接口定义为:

type MessageReader interface {
    ReceiveMessages([]Message)
}

但是你已经在SQSMessageReader 上定义了你的ReceiveMessages 方法,如下所示:

func (reader *SQSMessageReader) ReceiveMessages([]SQSMessage) {
}

因为它采用[]SQSMessage 参数而不是[]Message,它实现MessageReader 接口。你需要写:

func (reader *SQSMessageReader) ReceiveMessages([]Message) {
}

第二:

你写过:

func main() {
    var reader SQSMessageReader
    FuncNeedsReader(reader)
}

但是ReceiveMessages 有一个指针 接收器(func (reader *SQSMessageReader) ReceiveMessages...),所以你需要:

func main() {
    var reader SQSMessageReader
    FuncNeedsReader(&reader)
}

通过这两项更改,您的代码构建不会出错。

【讨论】:

  • 谢谢!我的理解是golang做静态接口检查,不递归检查一个函数的参数是否是另一个接口。这就是为什么在第一种情况下,函数只能采用确切的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多