在一个地方处理重复的错误情况

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

Handle repetitive error cases in one place

问题

我正在编写一个函数,将一个包含多个字段的结构体写入TCP连接。有没有一种方法可以像在Java中捕获异常一样,在一个地方处理错误?

我的实现如下:

  1. func writeFrame(frame *Frame, conn net.Conn) error {
  2. bo := binary.BigEndian
  3. if err := binary.Write(conn, bo, frame.ype); err != nil {
  4. return err
  5. }
  6. if err := binary.Write(conn, bo, frame.id); err != nil {
  7. return err
  8. }
  9. if err := binary.Write(conn, bo, frame.seq); err != nil {
  10. return err
  11. }
  12. if err := binary.Write(conn, bo, uint32(len(frame.arg1))); err != nil {
  13. return err
  14. }
  15. if err := binary.Write(conn, bo, uint32(len(frame.arg2))); err != nil {
  16. return err
  17. }
  18. if err := binary.Write(conn, bo, uint32(len(frame.arg3))); err != nil {
  19. return err
  20. }
  21. var csum uint32
  22. if err := binary.Write(conn, bo, csum); err != nil {
  23. return err
  24. }
  25. if _, err := conn.Write(frame.arg1); err != nil {
  26. return err
  27. }
  28. if _, err := conn.Write(frame.arg2); err != nil {
  29. return err
  30. }
  31. if _, err := conn.Write(frame.arg3); err != nil {
  32. return err
  33. }
  34. return nil
  35. }

这段代码的作用是将Frame结构体的多个字段写入TCP连接。如果在写入过程中出现错误,会在相应的位置返回错误。

英文:

I'm writing a function which writes a struct of multiple fields to a TCP connection. Is there a way to handle errors in one place like catching exception in Java?

My implementation looks like,

  1. func writeFrame(frame *Frame, conn net.Conn) error {
  2. bo := binary.BigEndian
  3. if err := binary.Write(conn, bo, frame.ype); err != nil {
  4. return err
  5. }
  6. if err := binary.Write(conn, bo, frame.id); err != nil {
  7. return err
  8. }
  9. if err := binary.Write(conn, bo, frame.seq); err != nil {
  10. return err
  11. }
  12. if err := binary.Write(conn, bo, uint32(len(frame.arg1))); err != nil {
  13. return err
  14. }
  15. if err := binary.Write(conn, bo, uint32(len(frame.arg2))); err != nil {
  16. return err
  17. }
  18. if err := binary.Write(conn, bo, uint32(len(frame.arg3))); err != nil {
  19. return err
  20. }
  21. var csum uint32
  22. if err := binary.Write(conn, bo, csum); err != nil {
  23. return err
  24. }
  25. if _, err := conn.Write(frame.arg1); err != nil {
  26. return err
  27. }
  28. if _, err := conn.Write(frame.arg2); err != nil {
  29. return err
  30. }
  31. if _, err := conn.Write(frame.arg3); err != nil {
  32. return err
  33. }
  34. return nil
  35. }

答案1

得分: 2

你可以创建一个简单的类型,用于存储一系列写操作,并在遇到错误时立即停止执行。

  1. type MyWriter struct {
  2. W io.Writer
  3. O binary.ByteOrder
  4. items []interface{}
  5. }
  6. func (w *MyWriter) AddWrite(value interface{}) {
  7. w.items = append(w.items, value)
  8. }
  9. // PerformWrite 执行通过 AddWrite 添加的所有写操作。
  10. // 在遇到错误时立即中止并返回错误。
  11. func (w *MyWriter) PerformWrites() error {
  12. for _, item := range w.items {
  13. if err := binary.Write(w.W, w.O, item); err != nil {
  14. return err
  15. }
  16. }
  17. return nil
  18. }

有了这个结构,你的 writeFrame 函数可能如下所示:

  1. func Write(conn net.Conn) error {
  2. w := MyWriter{W: conn, O: binary.BigEndian}
  3. // 队列化你的写操作(frame.type, frame.id, ...)
  4. w.AddWrite(int32(1))
  5. w.AddWrite(int32(2))
  6. w.AddWrite(int64(3))
  7. if err := w.PerformWrites(); err != nil {
  8. // 发生错误
  9. return err
  10. }
  11. return nil
  12. }
英文:

You could create a simple type that stores a bunch of writes and executes them all at once, bailing as soon as an error is encountered.

  1. type MyWriter struct {
  2. W io.Writer
  3. O binary.ByteOrder
  4. items []interface{}
  5. }
  6. func (w *MyWriter) AddWrite(value interface{}) {
  7. w.items = append(w.items, value)
  8. }
  9. // PerformWrite executes all writes that have been added via AddWrite.
  10. // It aborts as soon as an error is encountered and returns the error.
  11. func (w *MyWriter) PerformWrites() error {
  12. for _, item := range w.items {
  13. if err := binary.Write(w.W, w.O, item); err != nil {
  14. return err
  15. }
  16. }
  17. return nil
  18. }

With this in place, your writeFrame function might look something like this:

  1. func Write(conn net.Conn) error {
  2. w := MyWriter{W: conn, O: binary.BigEndian}
  3. // queue up your writes (frame.type, frame.id, ...)
  4. w.AddWrite(int32(1))
  5. w.AddWrite(int32(2))
  6. w.AddWrite(int64(3))
  7. if err := w.PerformWrites(); err != nil {
  8. // there was an error
  9. return err
  10. }
  11. return nil
  12. }

答案2

得分: 2

你可以使用bufio.Writer来实现这个功能。如果发生任何错误,未来的写入操作将简单地返回相同的错误并被忽略。

  1. func writeFrame(frame *Frame, conn net.Conn) error {
  2. bo := binary.BigEndian
  3. w := bufio.NewWriter(conn)
  4. binary.Write(w, bo, frame.ype)
  5. binary.Write(w, bo, frame.id)
  6. binary.Write(w, bo, frame.seq)
  7. binary.Write(w, bo, uint32(len(frame.arg1)))
  8. binary.Write(w, bo, uint32(len(frame.arg2)))
  9. binary.Write(w, bo, uint32(len(frame.arg3)))
  10. var csum uint32
  11. binary.Write(w, bo, csum)
  12. w.Write(frame.arg1)
  13. w.Write(frame.arg2)
  14. w.Write(frame.arg3)
  15. // 将未完成的数据写入 conn,并在发生错误时返回错误
  16. return w.Flush()
  17. }
英文:

You can use a bufio.Writer for this. If any error occurs future Write's will simply return the same error and be ignored.

  1. func writeFrame(frame *Frame, conn net.Conn) error {
  2. bo := binary.BigEndian
  3. w := bufio.NewWriter(conn)
  4. binary.Write(w, bo, frame.ype)
  5. binary.Write(w, bo, frame.id)
  6. binary.Write(w, bo, frame.seq)
  7. binary.Write(w, bo, uint32(len(frame.arg1)))
  8. binary.Write(w, bo, uint32(len(frame.arg2)))
  9. binary.Write(w, bo, uint32(len(frame.arg3)))
  10. var csum uint32
  11. binary.Write(w, bo, csum)
  12. w.Write(frame.arg1)
  13. w.Write(frame.arg2)
  14. w.Write(frame.arg3)
  15. // Write outstanding data to conn and return an error if any occured
  16. return w.Flush()
  17. }

1: http://golang.org/pkg/bufio/#Writer "bufio.Writer"

huangapple
  • 本文由 发表于 2015年1月13日 01:28:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/27907558.html
匿名

发表评论

匿名网友

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

确定