How can I write from multiple writers in golang?

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

How can I write from multiple writers in golang?

问题

创建一个函数,该函数将数据写入多个写入器,并返回每个写入器写入的字节数,返回的字节数的索引位置对应于写入器的索引位置。如果切片为空,则返回空切片([]int{})。

错误函数:

  1. type Errors []error
  2. func (m Errors) Error() string {
  3. count := 0
  4. for t := 0; t < len(m); t++ {
  5. if m[t] != nil {
  6. count += 1
  7. }
  8. }
  9. errindex := 0
  10. for t := 0; t < len(m); t++ {
  11. if m[t] != nil {
  12. errindex = t
  13. break
  14. }
  15. }
  16. if count == 0 {
  17. return fmt.Sprintf("(0 errors)")
  18. } else {
  19. if count == 1 {
  20. return fmt.Sprintf("%v", m[errindex])
  21. } else if count == 2 {
  22. return fmt.Sprintf("%v (and 1 other error)", m[errindex])
  23. } else {
  24. return fmt.Sprintf("%v (and %d other errors)", m[errindex], count-1)
  25. }
  26. }
  27. }

你的新代码:

  1. func WriteTo(b []byte, writers ...io.Writer) (n []int, errs errors.Errors) {
  2. if len(writers) == 0 {
  3. return []int{}, nil
  4. }
  5. for i := 0; i < len(writers); i++ {
  6. num, err := writers[i].Write(b) // 将字节写入当前写入器
  7. n = append(n, num) // 添加当前写入器写入的字节数
  8. if err != nil {
  9. switch err {
  10. case io.ErrShortWrite:
  11. errs = append(errs, err)
  12. default:
  13. errs = append(errs, err)
  14. }
  15. }
  16. }
  17. return n, errs
  18. }

你尝试修复代码,但有些测试未通过。你无法看出问题所在。当count == 1时,返回的是count == 0的情况,当count == 2时,返回的是count == 0的情况。

  1. []error{nil, io.ErrShortWrite, nil},
  2. []error{nil, io.ErrShortWrite, io.ErrShortWrite},

以上是测试用例。

英文:

The idea is to create a function that will write to several writers and do a return so that:

  • write the []byte slice to all writers
  • return n bytes written by each writer with index position corresponding to the index position of the writer.
    -if slice is empty return ([]int{})
    ... etc

Error function:

  1. type Errors []error
  2. func (m Errors) Error() string {
  3. count := 0
  4. for t := 0; t &lt; len(m); t++ {
  5. if m[t] != nil {
  6. count += 1
  7. }
  8. }
  9. errindex := 0
  10. for t := 0; t &lt; len(m); t++ {
  11. if m[t] != nil {
  12. errindex = t
  13. break
  14. }
  15. }
  16. if count == 0 {
  17. return fmt.Sprintf(&quot;(0 errors)&quot;)
  18. } else {
  19. if count == 1 {
  20. return fmt.Sprintf(&quot;%v&quot;, m[errindex])
  21. } else if count == 2 {
  22. return fmt.Sprintf(&quot;%v (and 1 other error)&quot;, m[errindex])
  23. } else {
  24. return fmt.Sprintf(&quot;%v (and %d other errors)&quot;, m[errindex], count-1)
  25. }
  26. }
  27. }

My new code:

  1. func WriteTo(b []byte, writers ...io.Writer) (n []int, errs errors.Errors) {
  2. if len(writers) == 0 {
  3. return []int{}, nil
  4. }
  5. for i := 0; i &lt; len(writers); i++ {
  6. num, err := writers[i].Write(b) // write bytes to a current writer
  7. n = append(n, num) // add bytes written by current write
  8. if err!=nil{
  9. switch err{
  10. case io.ErrShortWrite:
  11. errs = append(errs, err)
  12. default:
  13. errs = append(errs, err)
  14. }
  15. }
  16. }
  17. return n, errs
  18. }

I try to fix it but some tests don't pass. Can't really see the problem. Instead of returning when count == 1, returns when count == 0 and when count == 2, return as for count == 0

  1. []error{nil, io.ErrShortWrite, nil},
  2. []error{nil, io.ErrShortWrite, io.ErrShortWrite},

答案1

得分: 4

你可以使用io.MultiWriter()函数,它接受任意数量的io.Writer并返回一个单一的io.Writer,该写入器将数据复制到所有提供的写入器中。

例如:

  1. buf1 := &bytes.Buffer{}
  2. buf2 := &bytes.Buffer{}
  3. w := io.MultiWriter(buf1, buf2)
  4. if _, err := w.Write([]byte("Hello")); err != nil {
  5. panic(err)
  6. }
  7. fmt.Println("Buf1:", buf1.String())
  8. fmt.Println("Buf2:", buf2.String())

这将输出(在Go Playground上尝试):

  1. Buf1: Hello
  2. Buf2: Hello
英文:

You may use io.MultiWriter() which takes arbitrary number of io.Writers and returns a single io.Writer, which duplicates writes to all provided writers.

For example:

  1. buf1 := &amp;bytes.Buffer{}
  2. buf2 := &amp;bytes.Buffer{}
  3. w := io.MultiWriter(buf1, buf2)
  4. if _, err := w.Write([]byte(&quot;Hello&quot;)); err != nil {
  5. panic(err)
  6. }
  7. fmt.Println(&quot;Buf1:&quot;, buf1.String())
  8. fmt.Println(&quot;Buf2:&quot;, buf2.String())

This will output (try it on the Go Playground):

  1. Buf1: Hello
  2. Buf2: Hello

huangapple
  • 本文由 发表于 2021年9月18日 17:13:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/69233257.html
匿名

发表评论

匿名网友

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

确定