英文:
Handle repetitive error cases in one place
问题
我正在编写一个函数,将一个包含多个字段的结构体写入TCP连接。有没有一种方法可以像在Java中捕获异常一样,在一个地方处理错误?
我的实现如下:
func writeFrame(frame *Frame, conn net.Conn) error {
bo := binary.BigEndian
if err := binary.Write(conn, bo, frame.ype); err != nil {
return err
}
if err := binary.Write(conn, bo, frame.id); err != nil {
return err
}
if err := binary.Write(conn, bo, frame.seq); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg1))); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg2))); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg3))); err != nil {
return err
}
var csum uint32
if err := binary.Write(conn, bo, csum); err != nil {
return err
}
if _, err := conn.Write(frame.arg1); err != nil {
return err
}
if _, err := conn.Write(frame.arg2); err != nil {
return err
}
if _, err := conn.Write(frame.arg3); err != nil {
return err
}
return nil
}
这段代码的作用是将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,
func writeFrame(frame *Frame, conn net.Conn) error {
bo := binary.BigEndian
if err := binary.Write(conn, bo, frame.ype); err != nil {
return err
}
if err := binary.Write(conn, bo, frame.id); err != nil {
return err
}
if err := binary.Write(conn, bo, frame.seq); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg1))); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg2))); err != nil {
return err
}
if err := binary.Write(conn, bo, uint32(len(frame.arg3))); err != nil {
return err
}
var csum uint32
if err := binary.Write(conn, bo, csum); err != nil {
return err
}
if _, err := conn.Write(frame.arg1); err != nil {
return err
}
if _, err := conn.Write(frame.arg2); err != nil {
return err
}
if _, err := conn.Write(frame.arg3); err != nil {
return err
}
return nil
}
答案1
得分: 2
你可以创建一个简单的类型,用于存储一系列写操作,并在遇到错误时立即停止执行。
type MyWriter struct {
W io.Writer
O binary.ByteOrder
items []interface{}
}
func (w *MyWriter) AddWrite(value interface{}) {
w.items = append(w.items, value)
}
// PerformWrite 执行通过 AddWrite 添加的所有写操作。
// 在遇到错误时立即中止并返回错误。
func (w *MyWriter) PerformWrites() error {
for _, item := range w.items {
if err := binary.Write(w.W, w.O, item); err != nil {
return err
}
}
return nil
}
有了这个结构,你的 writeFrame
函数可能如下所示:
func Write(conn net.Conn) error {
w := MyWriter{W: conn, O: binary.BigEndian}
// 队列化你的写操作(frame.type, frame.id, ...)
w.AddWrite(int32(1))
w.AddWrite(int32(2))
w.AddWrite(int64(3))
if err := w.PerformWrites(); err != nil {
// 发生错误
return err
}
return nil
}
英文:
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.
type MyWriter struct {
W io.Writer
O binary.ByteOrder
items []interface{}
}
func (w *MyWriter) AddWrite(value interface{}) {
w.items = append(w.items, value)
}
// PerformWrite executes all writes that have been added via AddWrite.
// It aborts as soon as an error is encountered and returns the error.
func (w *MyWriter) PerformWrites() error {
for _, item := range w.items {
if err := binary.Write(w.W, w.O, item); err != nil {
return err
}
}
return nil
}
With this in place, your writeFrame
function might look something like this:
func Write(conn net.Conn) error {
w := MyWriter{W: conn, O: binary.BigEndian}
// queue up your writes (frame.type, frame.id, ...)
w.AddWrite(int32(1))
w.AddWrite(int32(2))
w.AddWrite(int64(3))
if err := w.PerformWrites(); err != nil {
// there was an error
return err
}
return nil
}
答案2
得分: 2
你可以使用bufio.Writer来实现这个功能。如果发生任何错误,未来的写入操作将简单地返回相同的错误并被忽略。
func writeFrame(frame *Frame, conn net.Conn) error {
bo := binary.BigEndian
w := bufio.NewWriter(conn)
binary.Write(w, bo, frame.ype)
binary.Write(w, bo, frame.id)
binary.Write(w, bo, frame.seq)
binary.Write(w, bo, uint32(len(frame.arg1)))
binary.Write(w, bo, uint32(len(frame.arg2)))
binary.Write(w, bo, uint32(len(frame.arg3)))
var csum uint32
binary.Write(w, bo, csum)
w.Write(frame.arg1)
w.Write(frame.arg2)
w.Write(frame.arg3)
// 将未完成的数据写入 conn,并在发生错误时返回错误
return w.Flush()
}
英文:
You can use a bufio.Writer for this. If any error occurs future Write's will simply return the same error and be ignored.
func writeFrame(frame *Frame, conn net.Conn) error {
bo := binary.BigEndian
w := bufio.NewWriter(conn)
binary.Write(w, bo, frame.ype)
binary.Write(w, bo, frame.id)
binary.Write(w, bo, frame.seq)
binary.Write(w, bo, uint32(len(frame.arg1)))
binary.Write(w, bo, uint32(len(frame.arg2)))
binary.Write(w, bo, uint32(len(frame.arg3)))
var csum uint32
binary.Write(w, bo, csum)
w.Write(frame.arg1)
w.Write(frame.arg2)
w.Write(frame.arg3)
// Write outstanding data to conn and return an error if any occured
return w.Flush()
}
1: http://golang.org/pkg/bufio/#Writer "bufio.Writer"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论