添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Exceptions 和 Return

Exceptions 和 Return

前几天 Thiago Pontes 分享了一篇关于异常被认为是反模式的博客给他的几个朋友。我对异常有一个不同的观点。我想如果写一个关于 exceptions 的博客会非常的有趣。我认为异常是一个非常好的功能,如果缺少异常可能会引起更大的错误。

这篇博客引用了我朋友分享的帖子: Python exceptions considered an anti-pattern.

没有异常的程序

如果你曾经用过 C 语言,你就记得 -1 和 NULL 作为返回值意味着错误,或者在这些情况下你需要记得去检查全局的错误号从而查出是否哪里出了问题。

如果一门语言不支持异常的话,那么你调用了一个方法,调用者就需要检查是否执行正确并且处理所有的错误。

例如, malloc() 这个函数,如果不能分配空间就返回 NULL,那你就必须检查返回值:

int *p;
p = malloc(sizeof(int) * 100);
if (p == NULL) {
    fprintf(stderr, "ERR: Cant allocate memory!");
    exit(1);

或者进一步演变的 例子来自于 libcurl 检查 url 是否能被访问 ,返回 CURLE_OK 表示没有错误。

#include <stdio.h>
#include <curl/curl.h>
int main(void)
  CURL *curl;
  CURLcode res;
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
   /* example.com is redirected, so we tell libcurl to follow redirection */
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
    /* always cleanup */
    curl_easy_cleanup(curl);
  return 0;

我之所以用 C 语言作为例子,是因为之前曾经用 C 语言检查错误。但是这个可以应用到其他不支持异常的语言上,例如 golang。

Golang 和 err

Go 是没有异常的,但是当在写一个方法时,通常的处理是返回一个结果和一个 error 的值。就想 http.Get 的做法一样:

// func Get(url string) (resp *Response, err error)
resp, err := http.Get("http://example.com/")

如果调用 Get 方法有任何的错误,那么变量 err 将捕获错误信息 , 如果没有错误那么它就是 nil 。对于每个人在 Go 和 kudos 里面这个是一个经典的写法。如果缺少异常,那么你必须了解隐含的错误信息。

让我们看看创建一个访问 URL 和读取返回数据头的方法:

Content-Type:
func GetContentType(url string) (string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    return resp.Header["Content-Type"][0], nil

上面的方法可以这样使用:

func main() {
    contentType, err := GetContentType("http://example.com")
    if err != nil {
        fmt.Println("Found unexpected error", err)
    } else {
        fmt.Printf("Content-Type: %s\n", contentType);