2

我在看 net/http 和 crypto/x509

我想知道哪种方法更好,为什么。

net/http/http.go 使用字符串:

// HTTP request parsing errors.
type ProtocolError struct {
  ErrorString string
}

func (err *ProtocolError) Error() string { return err.ErrorString }

var (
  ErrHeaderTooLong        = &ProtocolError{"header too long"}
  ErrShortBody            = &ProtocolError{"entity body too short"}
  ErrNotSupported         = &ProtocolError{"feature not supported"}
  ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
  ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
  ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
  ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
)

crypto/x509/verify.go 使用整数:

type InvalidReason int

const (
  TooManyIntermediates
  IncompatibleUsage
)

type CertificateInvalidError struct {
  Cert   *Certificate
  Reason InvalidReason
}

func (e CertificateInvalidError) Error() string {
  switch e.Reason {
  case TooManyIntermediates:
    return "x509: too many intermediates for path length constraint"
  case IncompatibleUsage:
    return "x509: certificate specifies an incompatible key usage"
  }
  return "x509: unknown error"
}
4

1 回答 1

1

两种用法都很好,但这取决于您的需求。

如果您发现将附加数据附加到错误消息中未显示的错误很有用,那么crypto/x509最好采用 in 的方法。

但我认为在大多数情况下,errors包中的简单错误字符串就足够了。

编辑

一个错误可以有不同的“属性”:

描述
Error() 方法应该返回一个简短的描述错误消息

可识别
通过让包导出它可能返回的不同错误,您可以识别它们。这可以像在io包中一样通过导出相同类型的初始化错误变量来完成:

if err == io.EOF { ... } // That's easy

或者encoding/json通过导出不同的错误类型在包中:

if mErr, ok := err.(*json.MarshalerError); ok { ... } // That's fairly easy

或者像他们在crypto/x509包中所做的那样,通过导出不同的原因(错误代码):

if e, ok := err.(x509.CertificateInvalidError); ok && e.Reason == x509.Expired  { ... } // Well, it works

唯一错误代码
如果由于协议规范错误应该具有特定代码,则这些代码可以嵌入到错误变量中。该crypto/x509软件包可能用于此目的,即使情况可能并非如此。

但是当谈到如何解决它时,我认为没有最好的方法,也没有任何明显惯用的方法。上面的示例向您展示了执行此操作的方法以及在标准库中执行此操作的方法。任你选。

..但可能不使用 switch 语句。

于 2013-07-11T14:13:00.243 回答