0

I have a bunch of *io.PipeWriter created and would like to make a multiwriter based on all those pipewriters in a function. So I call a function something like

func copyToWriters(reader *bufio.Reader, errs chan error, writers []*io.PipeWriter) {
  for _, writer := range writers {
    defer writer.Close()
  }
  mw := io.MultiWriter(writers)
  _, err := io.Copy(mw, reader)
  if err != nil {
    errs <- err
  }
}

I call the method with arguments copyToWriters(reader, errs, []*io.PipeWriter{w1, w2})

But it says cannot use writers (type []*io.PipeWriter) as type []io.Writer in argument to io.MultiWriter. But if I change io.MultiWriter(writers) to io.MultiWriter(writers[0],writers[1]) it works. How can I make the existing function work by not having to pass writers separately.

Vishnu
  • 4,377
  • 7
  • 26
  • 40
  • @Volker can you give the reason ? since `*io.PipeWriter` implements the `Writer` interface, it seems to be legitimate to use `*io.PipeWriter` instead of `io.PipeWriter`: https://golang.org/pkg/io/#PipeWriter – ymonad Feb 20 '17 at 05:42
  • why the downvote? – Vishnu Feb 20 '17 at 05:45
  • A, sorry, you are correct, PipeWriter is not an interface. Forget it. – Volker Feb 20 '17 at 09:25

1 Answers1

5

Unfortunately, Golang's type system does not allow casting []*io.PipeWriter to []io.Writer even when *io.PipeWriter implements io.Writer since it requires O(n) operation (reference).

The best you can do is create another []io.Writer and copy the pipe writers into it

ws := make([]io.Writer, len(writers))
for i, w := range writers {
    ws[i] = w
}
mw := io.MultiWriter(ws...)

And reason why you nead ..., read the document

Community
  • 1
  • 1
ymonad
  • 11,710
  • 1
  • 38
  • 49