英文:
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 interface和combining 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 
NewRTPWriteCloserfunction forRTPWriteCloserinterface, but we can not create first a writer then add Close function to it ? - Do I have to create a struct of 
RTPWriteCloserand 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)}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论