iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
Software Development

Go 語言學習手札系列 第 9

09 | 正衣冠、知興替、明得失

  • 分享至 

  • xImage
  •  

唐貞觀十七年,魏徵病死了,唐太宗很難過,流着眼淚說:「夫以銅為鏡,可以正衣冠,以史為鏡,可以知興替,以人為鏡,可以明得失。魏徵沒,朕亡一鏡矣!」

如同唐太宗所言,錯誤可以被視為一種有價值的鏡子,幫助我們更好地理解和改進我們的程式 錯誤。

Golang 中的 Errors 提供了一個結構化的方式來 處理記錄 錯誤,可以幫助我們識別程式中的問題,還可以幫助我們追蹤錯誤的源頭,並提供資訊以便修復。

Errors

Errors 是一種用於表示程式 執行期間 發生問題異常 情況的機制。Go 中的錯誤通常是一個回傳 error 介面的類型,這個介面只有一個 Error() 方法,他返回一個 描述錯誤string 。錯誤用於顯示某些操作無法成功完成,並提供有關問題的資訊。

舉例:

package main

import (
	"errors"
	"fmt"
)

func divide(a, b float64) (float64, error) {
	if b == 0 {
		// 如果除數是零,返回一個錯誤
		return 0, errors.New("無法執行除法,除數不能為零")
	}
	return a / b, nil
}

func main() {
	result, err := divide(10, 0)
	if err != nil {
		// 如果錯誤不為空,表示除法操作出現問題
		fmt.Println("錯誤:", err)
	} else {
		fmt.Println("結果:", result)
	}
}
錯誤: 無法執行除法,除數不能為零

Panic

panic 是一種用於表示程式遇到 無法恢復錯誤異常 情況時的 機制 。當程式碼遇到 panic 時,它會 立即停止執行 目前的函數,並同時觸發一個運行時錯誤,也會印出錯誤的訊息,讓人瞭解問題。直到整個程序停止運行。 panic 用於處理不應該發生的錯誤。

舉例:

package main

import "fmt"

func main() {
    divideByZero(5, 0)

    // 這行代碼不會執行,因為前一行觸發了 panic
    fmt.Println("這行代碼不會執行")
}

func divideByZero(a, b int) {
    if b == 0 {
        // 使用 panic 函數觸發一個 panic,並提供錯誤訊息
        panic("除數不能為零")
    }
    result := a / b
    fmt.Println("結果:", result)
}
panic: 除數不能為零

Recover

recover 用於 處理 panic 錯誤的內建函數 。發生 panic 時,使程序能夠進行一些 清理 工作,並 嘗試恢復 正常的執行流程。當 recover 函數 被呼叫 時,它會 停止panic 的傳播,並返回觸發 panic 的錯誤訊息。如果 recover 在非 panic 的狀態下被呼叫,它將返回 nil。

package main

import "fmt"

func main() {
	// 嘗試執行一個可能觸發 panic 的函數
	safeDivide(10, 0)
	fmt.Println("執行正常流程")
}

func safeDivide(a, b int) {
	// 使用 defer 延遲執行 recover 函數,以捕獲 panic
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("讀取到 panic,錯誤訊息:", r)
		}
	}()

	if b == 0 {
		// 觸發 panic,因為除數為零
		panic("除數不能為零")
	}

	result := a / b
	fmt.Println("結果:", result)
}
取到 panic,錯誤訊息: 除數不能為零
執行正常流程

Embedding

Embedding 通常指的是一種在 struct嵌入 其他結構類型 的方式,以便在 新結構中 使用嵌入的結構的字段和方法。

舉例:
一個圖形繪制系統,可以畫出多種不同的圖形類型,比如圓形和矩形。這些圖形都有一些 共同的屬性 ,比如位置和顏色,但也有一些 特定 於每種圖形類型的屬性和行為。

package main

import (
	"fmt"
)

// 創建一個通用的圖形結構,包含了所有圖形都共有的屬性
type Shape struct {
	X, Y  int    // 圖形的位置
	Color string // 圖形的顏色
}

// 定義一個 Circle 結構,並嵌入通用的圖形結構
type Circle struct {
	Shape      // 嵌入通用的圖形結構
	Radius int // 圓形特有的屬性
}

// 定義一個 Rectangle 結構,並嵌入通用的圖形結構
type Rectangle struct {
	Shape             // 嵌入通用的圖形結構
	Width, Height int // 矩形特有的屬性
}

func main() {
	// 創建一個圓形
	circle := Circle{
		Shape:  Shape{X: 10, Y: 10, Color: "紅色"},
		Radius: 5,
	}

	// 創建一個矩形
	rectangle := Rectangle{
		Shape:  Shape{X: 20, Y: 20, Color: "藍色"},
		Width:  10,
		Height: 15,
	}
    // 印出圓形
	fmt.Println("圓形的位置:", circle.X, circle.Y)
	fmt.Println("圓形的顏色:", circle.Color)
	fmt.Println("圓形的半徑:", circle.Radius)

    // 印出矩形
	fmt.Println("矩形的位置:", rectangle.X, rectangle.Y)
	fmt.Println("矩形的顏色:", rectangle.Color)
	fmt.Println("矩形的寬度:", rectangle.Width)
	fmt.Println("矩形的高度:", rectangle.Height)
}
圓形的位置: 10 10
圓形的顏色: 紅色
圓形的半徑: 5
矩形的位置: 20 20
矩形的顏色: 藍色
矩形的寬度: 10
矩形的高度: 15

碎語

Go 的 panic 會印出些錯誤的資訊,可以從中去檢查及調整程式碼,理性多了!妳各位 panic 的時候,誰不會emotional 或內耗?
猛然發現週末真危險,一鬆懈就差點來不及發文。
今天除了 Error 還稍稍提了點 Embedding


上一篇
08 | 誰真的需要博愛座?
下一篇
10 | 能者高效不過勞
系列文
Go 語言學習手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言