V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
geebos
V2EX  ›  问与答

Go 为什么不能采用抛出错误的方式处理错误

  •  
  •   geebos · 2020-12-31 17:54:14 +08:00 · 2816 次点击
    这是一个创建于 1429 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,Go 为什么不采用类似 Java 的抛出错误的错误处理方式。现在这种错误处理太麻烦了,一个函数一半是在做错误处理。

    26 条回复    2021-01-02 13:23:15 +08:00
    dilu
        1
    dilu  
       2020-12-31 17:56:24 +08:00
    真·月经帖
    jazzychai
        2
    jazzychai  
       2020-12-31 17:56:48 +08:00
    不想处理就 _ 啊
    shoaly
        3
    shoaly  
       2020-12-31 17:58:53 +08:00
    .....其实 这个错误和 java 新手的通篇 try catch 是一样一样的
    geebos
        4
    geebos  
    OP
       2020-12-31 18:00:14 +08:00
    @jazzychai 我指的不是不想处理,是需要把错误集中在调用的函数去处理
    wunonglin
        5
    wunonglin  
       2020-12-31 18:02:00 +08:00
    不要带着 java 的感觉去用 go
    BeautifulSoap
        6
    BeautifulSoap  
       2020-12-31 18:02:51 +08:00 via Android
    @geebos 我寻思这个需求和你用不用 go 的错误处理没关系啊
    geebos
        7
    geebos  
    OP
       2020-12-31 18:03:36 +08:00
    @shoaly 我指的不是这个,我的烦的是要手动处理和返回错误,Java 至少出错会自动抛出。
    shoaly
        8
    shoaly  
       2020-12-31 18:06:13 +08:00
    明白了, java 你写的时候 一般 ide 会帮你 throw 异常, go 这个缺了
    geebos
        9
    geebos  
    OP
       2020-12-31 18:08:55 +08:00
    @shoaly 什么 IDE,你是不是对 Java 有什么误解,throw 异常是 Java 做的,和 IDE 没关系。
    geebos
        10
    geebos  
    OP
       2020-12-31 18:23:57 +08:00
    @BeautifulSoap 我就是想用错误处理啊,但是 Go 没有。现在的方案全部要手动 wrap,一排代码下来,每一个函数调用都要写几行错误处理的代码,我心态炸了呀。
    cnbattle
        11
    cnbattle  
       2020-12-31 20:43:19 +08:00 via Android
    不是处理,用 recover 捕捉也行啊
    BeautifulSoap
        12
    BeautifulSoap  
       2020-12-31 20:54:12 +08:00
    @geebos "Java 至少出错会自动抛出" 排除掉运行时的错误(除以 0,空指针之类的) java 抛错误也都是要你手动 throw 一个异常的,没理解你说的出错自动抛出的意思
    AndyAO
        13
    AndyAO  
       2020-12-31 21:09:28 +08:00
    不太懂 GO.

    如果是我,会先了解 GO 这样设计的原因,一般而言,在比较好的书中应该都有讲述.看来你是个比较着急的人,没有仔细了解设计就开始用这门语言了,和我的做法不太相同.

    不过,很多人其实对 Java 常常抛异常这件事情本身就是感到很厌恶的.

    > Exception handling is one of the worst sources of complexity in software systems. Code that deals with special conditions is inherently harder to write than code that deals with normal cases, and developers often define exceptions without considering how they will be handled.
    > From:*‪Philosophy_of_Software_Design*

    盲猜 GO 这么做就是为了让你尽量远离抛异常.
    TypeError
        14
    TypeError  
       2020-12-31 21:16:07 +08:00
    golang 开发团队提出过 try 的方案,被社区否决了

    而且我觉得严重错误用 panic/recovery 、普通错误用返回值处理,也没啥不好的

    go 的问题是简陋了点,要手写一堆 if err
    如果像 rust 那样 Result + 模式匹配就优雅多了
    SuperMild
        15
    SuperMild  
       2020-12-31 21:23:08 +08:00
    go 这种方式也有好处,只是少了个语法糖,如果加一个 check err 语法糖,有错就立即返回错误,没错就继续执行,那就舒服多了。
    geebos
        16
    geebos  
    OP
       2020-12-31 21:52:42 +08:00
    @BeautifulSoap 我的意思是 Java 异常可以自动向外层函数抛出,而 Go 还要手动返回。假如是三层函数调用,Go 每一层都要手动返回,不然外层的函数就收不到错误。而 Java 就不需要,只要中间的函数没有 catch 错误会继续往外层函数传递。
    Vedar
        17
    Vedar  
       2020-12-31 22:18:20 +08:00
    @geebos panic 不就是这样子么 不处理就整个 goroutine 崩掉
    geebos
        18
    geebos  
    OP
       2020-12-31 22:57:41 +08:00
    @Vedar 但是我不能捕获 panic 啊,这就是问题所在了
    cheng6563
        19
    cheng6563  
       2020-12-31 23:01:59 +08:00 via Android
    不要把 c 看成太高级的语言,把他看成 c 的优化版就行了
    cheng6563
        20
    cheng6563  
       2020-12-31 23:02:25 +08:00 via Android
    不要把 go 看成太高级的语言,把他看成 c 的优化版就行了
    raaaaaar
        21
    raaaaaar  
       2020-12-31 23:04:47 +08:00 via Android
    不想作为返回值就 panic
    BeautifulSoap
        22
    BeautifulSoap  
       2020-12-31 23:21:12 +08:00 via Android
    @geebos panic 能捕获啊,只不过函数内部无法像有异常机制的语言那样针对特定的代码段 try catch 罢了
    。但你的需求是:程序出异常时顺着调用栈一路上抛然后集中处理。这点 panic 是完全可以胜任的

    以及 go 语言使用 error 返回值也完全能实现将错误一路上抛的功能(只要你的程序对所有函数调用的 error 做处理就行,没你想得那么麻烦,ide 都是自动生成的)
    学习一门语言就应该尝试遵循它的语言哲学,虽然 go 的这 error 返回值的确啰嗦了点,但是并不一定差于 try catch
    我对 go 的 error 最大的不满也就是标准库里生成的 error 不带调用栈,导致错误一路返回到最顶层后完全不知道这错误的发生在哪里。不过这个问题解决起来也不难就是了
    Bazingal
        23
    Bazingal  
       2021-01-01 10:03:39 +08:00 via Android
    不懂 go,用返回值的方式返回错误,会自动带上堆栈吗
    geebos
        24
    geebos  
    OP
       2021-01-02 13:10:00 +08:00
    @BeautifulSoap 你说的很对,可能我以前用 Python 习惯了,突然转到 Go 有点受不了。但我觉的这也不能算作 Go 的哲学,反而更像设计时没有考虑到。不只是错误处理,还有变量声明的语法(使用 var 的时候不能进行初始化)、返回值设置了名字之后还需要手动 return 等等。至少在语法和错误处理方面我没看到 Go 的哲学。
    BeautifulSoap
        25
    BeautifulSoap  
       2021-01-02 13:20:11 +08:00
    @geebos 带着偏见你永远看什么都是不行,编程语言本来就是多样性的,没有一个语言的语法必须怎样怎样的规定,你熟悉了一门语言很自然得会觉得所有语言都应该如此,但是这种思维作为程序员来说并不好
    BeautifulSoap
        26
    BeautifulSoap  
       2021-01-02 13:23:15 +08:00
    @Bazingal 官方包里的不会带上堆栈,虽说用个第三方包,或者项目里自己给 error 加个堆栈就能解决,但是不是官方支持的确不好。这是目前用起来最不爽的地方
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2838 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 03:46 · PVG 11:46 · LAX 19:46 · JFK 22:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.