尝试了monad模式,但仍然有重复的错误处理

I read Rob Pike's post but it only works for repetitive loops. I, on the other hand, have this. Notice how I added the err field, accessible via the Error() method, in a futile attempt to reduce the if errs.

The code above is simpler, but the ReadRLP() function is no different from just returning a err. Is there some pattern that can help with this?

type namePreclaimRLP struct {
    ObjectTag         uint
    RlpMessageVersion uint
    AccountID         []uint8
    AccountNonce      uint64
    CommitmentID      []uint8
    Fee               big.Int
    TTL               uint64
    err               error
}

func (n *namePreclaimRLP) ReadRLP(s *rlp.Stream) (aID, cID string) {
    blob, err := s.Raw()
    if err != nil {
        n.err = err
    }
    err = rlp.DecodeBytes(blob, n)
    if err != nil {
        n.err = err
    }
    _, aID, err = readIDTag(n.AccountID)
    if err != nil {
        n.err = err
    }
    _, cID, err = readIDTag(n.CommitmentID)
    if err != nil {
        n.err = err
    }
    return aID, cID
}

func (n *namePreclaimRLP) Error() (err error) {
    return n.err
}

Your code doesn't compile as written (there are a lot of missing types), so I can't fully test this code, but I would expect something along these lines, returning err in the typical Go approach, rather than making it part of another type, which is unusual and a bit confusing:

func (n *namePreclaimRLP) ReadRLP(s *rlp.Stream) (aID, cID string, err error) {
    var blob SomeType // Depends on what blob actually is
    if blob, err = s.Raw(); err != nil {
        return
    }

    if err = rlp.DecodeBytes(blob, n); err != nil {
        return
    }

    if _, aID, err = readIDTag(n.AccountID); err != nil {
        return
    }

    _, cID, err = readIDTag(n.CommitmentID)

    return
}

I'd delete your Error() function here and the err field. namePreclaimRLP is not a kind of error. It feels you're abusing the interface there.

Use the following to reduce the amount of code and retain an more idiomatic API by returning an error.

func (n *namePreclaimRLP) ReadRLP(s *rlp.Stream) (aID, cID string, err error) {
    se := func(e error) {
       if e != nil {
          err = e
       }
    }

    blob, e := s.Raw()
    se(e)
    se(rlp.DecodeBytes(blob, n))
    _, aID, e = readIDTag(n.AccountID)
    se(e)
    _, cID, e = readIDTag(n.CommitmentID)
    se(e)
    return
}