如何通过组合来自不同包的接口来创建一个接口?

huangapple go评论79阅读模式
英文:

How to create an interface by combining interfaces from different packages?

问题

情况

我正在使用pion/rtpio包的代码库。

我试图通过为接口RTPwriter添加一个Close()函数来扩展它。目标是创建一个NewRTPWritCloser()函数,返回一个具有合并函数的writeCloser。

从该包中,我看到作者已经创建了接口RTPWriteCloser

type RTPWriteCloser interface {
	RTPWriter
	io.Closer
}

尝试

我创建了以下代码以重用函数,但这是错误的,因为我还不知道替代方法:


func NewRTPWriteCloser(wc io.WriteCloser) rtpio.RTPWriteCloser {
	writeCloser := rtpio.NewRTPWriter(wc)
	return writeCloser
}

我期望wc已经有自己的Close()函数,所以返回的writeCloser将满足接口RTPWriteCloser。然而,我得到了一个错误(missing method Close)

函数NewRTPWriter()如下所示:

func NewRTPWriter(w io.Writer) RTPWriter {
	return &RawRTPWriter{
		dst: w,
	}
}

问题

  • 如何同时创建一个具有多个嵌入接口的所需函数的实例,以满足嵌入接口?
  • 在这个例子中,我们想要为RTPWriteCloser接口创建NewRTPWriteCloser函数,但我们不能先创建一个writer,然后再为其添加Close函数吗?
  • 我是否必须创建一个RTPWriteCloser的结构体,并重写所有需要接受该结构体的必要函数?(似乎效率低下)

搜索

我自己搜索了一些例子:interfaces inside interfacecombining or extending interfaces,但它们没有解决我的问题。

英文:

Situation

For code base I am using pion/rtpio package.

I am trying to extend the interface RTPwriter by adding a Close() function to it. The goal is to make a NewRTPWritCloser() function that return a writeCloser with the combined functions.

From the package, I see the author already created the interface RTPWriteCloser

type RTPWriteCloser interface {
	RTPWriter
	io.Closer
}

Attempt

I made this to reuse the function, which is wrong but I didn't know the alternative yet:


func NewRTPWriteCloser(wc io.WriteCloser) rtpio.RTPWriteCloser {
	writeCloser := rtpio.NewRTPWriter(wc)
	return writeCloser
}

and expected that the wc have its own Close() function ready, so the returned writeCloser will satisfy the interface RTPWriteCloser. However, I got (missing method Close) as an error.

The function NewRTPWriter() is like this:

func NewRTPWriter(w io.Writer) RTPWriter {
	return &RawRTPWriter{
		dst: w,
	}
}

Questions

  • How do we create an instance with all desired functions from multiple embedded interfaces at the same time to satisfy the embedding interface ?
  • In this example, we want to create NewRTPWriteCloser function for RTPWriteCloser interface, but we can not create first a writer then add Close function to it ?
  • Do I have to create a struct of RTPWriteCloser and rewrite all necessary functions that take in that struct ? (seems inefficient)

Searched

I did my own searching for example: interfaces inside interface and combining or extending interfaces, but they don't get me to the end to understand my problem.

答案1

得分: 1

我相信你需要按照你的建议创建一个新的结构体来实现你的接口,我们称之为RawRTPWriterCloser,并添加Close()方法的实现。

你可以在其他结构体中嵌入结构体,所以Close()方法是你需要额外定义的唯一函数:

type RawRTPWriterCloser struct {
    rtpio.RawRTPWriter
}

func (rw *RawRTPWriterCloser) Close() error {
    panic("在这里添加实现")
}
英文:

I believe you will need to create a new struct as you suggest to implement your interface, let's call it RawRTPWriterCloser and add the implementation for Close().

You can embed structs in other structs however, so the Close() method is the only function you'll need to additionally define:

type RawRTPWriterCloser struct {
    rtpio.RawRTPWriter
}

func (rw *RawRTPWriterCloser) Close() error {
    panic("add implementation here")
}

答案2

得分: 1

你应该定义一个适配器结构体,将io.Closer的语义添加到你的基本类型中:

type WrappingRTPWriteCloser struct {
    w RTPWriter
    c io.Closer
}

然后,你应该定义Close方法来满足接口:

func (w *WrappingRTPWriteCloser) Close() error {
    return w.c.Close()
}

接下来,你应该在实例创建时创建一个新的包装结构体的引用:

func NewRTPWriteCloser(wc io.WriteCloser) rtpio.RTPWriteCloser {
    writeCloser := WrappingRTPWriteCloser{
        w: rtpio.NewRTPWriter(wc),
        c: wd,
    }
    return writeCloser
}

另一种解决方案是使用该包提供的RTPPipe函数,它会返回一个RTPReadCloser和一个RTPWriteCloser实例(将RTPReadCloser的输入导向RTPWriteCloser的输出):

// RTPPipe创建一个新的RTPPipe并返回读取器和写入器。
func RTPPipe() (RTPReadCloser, RTPWriteCloser) {
    r, w := io.Pipe()
    return &pipeRTPReader{closer: r, rtpReader: NewRTPReader(r, 1500)}, &pipeRTPWriter{closer: w, rtpWriter: NewRTPWriter(w)}
}
英文:

You should define a adapter struct, adding the io.Closer semantics to your base type:

type WrappingRTPWriteCloser struct {
    w RTPWriter
    c io.Closer
}

You should then define the Close method to satisfy the interface:

func (w *WrappingRTPWriteCloser) Close() error {
    return w.c.Close()
}

Then you should create a new reference of your wrapping struct, upon an instance creation:

func NewRTPWriteCloser(wc io.WriteCloser) rtpio.RTPWriteCloser {
    writeCloser := WrappingRTPWriteCloser{
            w: rtpio.NewRTPWriter(wc),
            c: wd,
    }
    return writeCloser
}

An alternative solution, would be to use the RTPPipe function provided out of the box by the package and which returns both an RTPReadCloser and a RTPWriteCloser instance (piping the RTPReadCloser input to the RTPWriteCloser output):

// RTPPipe creates a new RTPPipe and returns the reader and writer.
func RTPPipe() (RTPReadCloser, RTPWriteCloser) {
	r, w := io.Pipe()
	return &pipeRTPReader{closer: r, rtpReader: NewRTPReader(r, 1500)}, &pipeRTPWriter{closer: w, rtpWriter: NewRTPWriter(w)}
}

huangapple
  • 本文由 发表于 2022年7月22日 16:46:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/73077586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定