加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

一文悟透备受争议的 Go 说话错误处理赏罚

发布时间:2019-09-23 22:33:38 所属栏目:建站 来源:佚名
导读:写过 C 的同窗知道,C 说话中经常返回整数错误码(errno)来暗示函数处理赏罚堕落,凡是用 -1 来暗示错误,用 0 暗示正确。 而在 Go 中,我们行使 error 范例来暗示错误,不外它不再是一个整数范例,是一个接口范例: typeerrorinterface{ Error()string } 它表
副问题[/!--empirenews.page--]

写过 C 的同窗知道,C 说话中经常返回整数错误码(errno)来暗示函数处理赏罚堕落,凡是用 -1 来暗示错误,用 0 暗示正确。

一文悟透备受争议的 Go 说话错误处理赏罚

而在 Go 中,我们行使 error 范例来暗示错误,不外它不再是一个整数范例,是一个接口范例:

  1. type error interface { 
  2.  Error() string 

它暗示那些能用一个字符串就能说清的错误。

我们最常用的就是 errors.New() 函数,很是简朴:

  1. // src/errors/errors.go 
  2. func New(text string) error { 
  3.     return &errorString{text} 
  4. type errorString struct { 
  5.     s string 
  6. func (e *errorString) Error() string { 
  7.     return e.s 

行使 New 函数建设出来的 error 范例现实上是 errors 包里未导出的 errorString 范例,它包括独一的一个字段 s,而且实现了独一的要领:Error() string。

凡是这就够了,它能反应其时“堕落了”,可是有些时辰我们必要越发详细的信息,譬喻:

  1. func Sqrt(f float64) (float64, error) { 
  2.  if f < 0 { 
  3.  return 0, errors.New("math: square root of negative number") 
  4.  } 
  5.  // implementation 

当挪用者发明堕落的时辰,只知道传入了一个负数进来,并不清晰到底传的是什么值。在 Go 里:

  1. It is the error implementation’s responsibility to summarize the context. 

它要求返回这个错误的函数要给出详细的“上下文”信息,也就是说,在 Sqrt 函数里,要给出这个负数到底是什么。

以是,假如发明 f 小于 0,应该这样返回错误:

  1. if f < 0 { 
  2.  return 0, fmt.Errorf("math: square root of negative number %g", f) 

这就用到了 fmt.Errorf 函数,它先将字符串名目化,再挪用 errors.New 函数来建设错误。

当我们想知道错误范例,而且打印错误的时辰,直接打印 error:

  1. fmt.Println(err) 

可能:

  1. fmt.Println(err.Error) 

fmt 包会自动挪用 err.Error() 函数来打印字符串。

凡是,我们将 error 放到函数返回值的最后一个,没什么好说的,各人都这样做,约定俗成。

参考资料【Tony Bai】这篇文章提到,结构 error 的时辰,要求传入的字符串首字母小写,末了不带标点标记,这是由于我们常常会这样行使返回的 error:

  1. ... err := errors.New("error example") 
  2. fmt.Printf("The returned error is %s.n", err) 

error 的困局

  1. In Go, error handling is important. The language’s design and conventions encourage you to explicitly check for errors where they occur (as distinct from the convention in other languages of throwing exceptions and sometimes catching them). 

在 Go 说话中,错误处理赏罚长短常重要的。它从说话层面要求我们必要明晰地处理赏罚碰着的错误。而不是像其他说话,类如 Java,行使 try-catch- finally 这种“花招”。

这就造成代码里 “error” 满天飞,显得很是冗长拖拉。

而为了代码结实性思量,对付函数返回的每一个错误,我们都不能忽略它。由于堕落的同时,很也许会返回一个 nil 范例的工具。假如差池错误举办判定,那下一行对 nil 工具的操纵百分之百会激发一个 panic。

这样,Go 说话中诟病最多的就是它的错误处理赏罚方法好像回到了上古 C 说话期间。

  1. rr := doStuff1() 
  2. if err != nil { 
  3.  //handle error... 
  4. err = doStuff2() 
  5. if err != nil { 
  6.  //handle error... 
  7. err = doStuff3() 
  8. if err != nil { 
  9.  //handle error... 

Go authors 之一的 Russ Cox 对付这种概念举办过批判:当初选择返回置魅这种错误处理赏罚机制而不是 try-catch,首要是思量前者合用于大型软件,后者更得当小措施。

在参考资料【Go FAQ】里也提到,try-catch 会让代码变得很是紊乱,措施员会倾向将一些常见的错误,譬喻,failing to open a file,也抛到非常里,这会让错误处理赏罚越发冗长繁琐且易堕落。

而 Go 说话的多返回值使得返回错误非常简朴。对付真正的非常,Go 提供 panic-recover 机制,也使得代码看起来很是简捷。

虽然 Russ Cox 也认可 Go 的错误处理赏罚机制对付开拓职员简直有必然的心智承担。

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读