iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0

前言


剛開始寫Golang的時候
我真的好討厭error的處理
一直重複的if err
覺得好醜
不能簡潔一點嗎?
因此花了時間找,是不是有更好的寫法,有更好的package ?
(Golang官方有個errors包)
但後來寫久了
慢慢熱衷每個error都要處理
甚至用errorcheck檢查
連這種最簡單的error,我都不放過/images/emoticon/emoticon27.gif

defer db.close()

本文


我們來看看Go和Jave處理錯誤的差異

  • Go 範例
    在 Go 中,當一個函數可能返回多個錯誤時,你需要一個一個返回error
package main

import (
    "errors"
    "fmt"
)

func processA() error {
    return errors.New("error in process A")
}

func processB() error {
    return errors.New("error in process B")
}

func main() {
    if err := processA(); err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    if err := processB(); err != nil {
        fmt.Println("Error:", err)
        return
    }

    fmt.Println("All processes succeeded")
}
  • Java 範例
    Java 可以在一個 try 塊中捕獲多個異常,並用不同的 catch 塊來處理。
    (Python 也有try-exception)
public class Main {
    public static void processA() throws Exception {
        throw new Exception("Error in process A");
    }

    public static void processB() throws Exception {
        throw new Exception("Error in process B");
    }

    public static void main(String[] args) {
        try {
            processA();
            processB();
            System.out.println("All processes succeeded");
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

比較結果:

  • Golang:每次函數調用後都要,不厭其煩,明確地檢查錯誤。
  • Java:可以通過 try-catch 捕獲多個異常,但異常的處理邏輯較為隱晦,因為它將錯誤處理與正常流程分開。

在Golang的世界,要把握當下錯誤
在Golang的世界,強調每個錯誤都要即刻處理,寫的時候覺得厭煩 眼神死
但處理的時候一目了然,簡單明瞭。

前一章講到的interface,其設計方向也是走簡單自然大道
Golang的第一代掌門人Rob Pike曾說

Don’t design with interfaces, discover them.

Rob 在這裡指出,你不需要事先去思考需要哪些抽象。你可以從具體的結構體開始設計,只有當設計真正需要時再創建介面。這樣,你的程式碼會隨著需求自然成長,達到預期的設計。

這個也是跟Java不一樣的地方
相對來說,Java的設計模式更傾向於一開始就思考抽象的介面,通過強類型的多態性和繼承機制來構建更結構化的系統。這在某些情況下可能導致過度設計,創建出許多不必要的抽象。

還有Golang的世界
不僅沒有try-catch的機制
還有一堆東西沒有,清單如下 註1

  • regular syntax (don't need a symbol table to parse)
  • garbage collection (only)
  • no header files
  • explicit dependencies
  • no circular dependencies
  • constants are just numbers
  • int and int32 are distinct types
  • letter case sets visibility
  • methods for any type (no classes)
  • no subtype inheritance (no subclasses)
  • package-level initialization and well-defined order of initialization
  • files compiled together in a package
  • package-level globals presented in any order
  • no arithmetic conversions (constants help)
  • interfaces are implicit (no "implements" declaration)
  • embedding (no promotion to superclass)
  • methods are declared as functions (no special location)
  • methods are just functions
  • interfaces are just methods (no data)
  • methods match by name only (not by type)
  • no constructors or destructors
  • postincrement and postdecrement are statements, not expressions
  • no preincrement or predecrement
  • assignment is not an expression
  • evaluation order defined in assignment, function call (no "sequence point")
  • no pointer arithmetic
  • memory is always zeroed
  • legal to take address of local variable
  • no "this" in methods
  • segmented stacks
  • no const or other type annotations
  • no templates
  • no exceptions
  • builtin string, slice, map
  • array bounds checking

在Golang的1.18之前甚至還沒有泛型
沒出來之前還很期待它!!
後來發現好像還好,沒有常用到 而且泛型設計,我覺得看起來有點醜
更讓我體驗到Golang設計之美。

不過第一代掌門人Rob Pike已經退隱
現在已經是第三代接手
最近的Golang發展也飽受爭議
1.23版的iterator,許多人有說破壞Golang的設計哲學-簡單至上
Aliaksandr Valialkin(fasthttp的作者)
還寫了一篇文章直指Golang往錯誤方向走 註2


結語


我用一段reddit討論iterator的爭議(註3),其中一人的留言

至於Go的高生產力,這是因為它作為一門語言很“無聊”。它並不試圖變得“聰明”,而是希望人們用它來解決問題,而不是在語言本身上解決問題。
這也是我和很多人喜歡Go的原因之一。它讓你專注於問題本身,而不是像現代C++和Rust那樣,讓你糾結於語言的複雜性。

Note:C++ 語法真的可怕XDD


** 引用

註1
Rob Pike的 simplicity-is-complicated
https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html
註2
Aliaksandr Valialkin的文章
https://valyala.medium.com/go-evolves-in-the-wrong-direction-7dfda8a1a620
註3
reddit的討論
https://www.reddit.com/r/golang/comments/1dhxy1u/why_people_are_angry_over_go_123_iterators/


上一篇
Day02-到底是誰的interface
下一篇
DAY04-Go-我說在座的各位都是垃圾--回收要注意的事
系列文
那些年,我們一起走過的Go錯6
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言