简体   繁体   中英

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

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.

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")
}

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)}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM