保證型別安全:使用Go的Type Assertions避免型別錯誤

更新於 2024/09/04閱讀時間約 9 分鐘


raw-image

👨‍💻簡介

在Go中,假如我要判斷一個資料類型是甚麼,該怎麼做呢? Golang有一個功能叫做Type Assertions(類型斷言),它的作用就是能夠在運行時檢查我的資料類型,讓我在傳遞類型時能確保資料類型是正確的。

Type Assertions 的基本概念

在Go中,Type Assertions的主要目的是在運行時將 interface 型別的值轉換為特定的實際型別。interface 是一種特殊的類型,它可以保存任何值的實例,但在運行時,我們可能需要確定該值的實際類型以執行相應的操作,以確保我們能夠安全地操作資料,這就是Type Assertions的作用。

Type Assertions的基本語法如下:

value, ok := someInterface.(T)

這個表達式意思為將someInterface轉換為類型T。如果成功,它將value設置為轉換後的值,並將ok設置為true。如果轉換失敗,則value將是零值,而ok將是false

Type Assertions的用途

Type Assertions 的主要用途包括:

  1. 資料型別的轉換

當我們處理interface型別的資料時,可能需要將其轉換為具體的型別,以便進行特定操作。

func process(someInterface interface{}) {
if str, ok := someInterface.(string); ok {
// 將interfacce轉換為string類型並進行操作
fmt.Printf("Length of string: %d\n", len(str))
} else {
fmt.Println("Not a string")
}
}

2. 確保型別的正確性

使用 Type Assertions,我們可以在執行特定操作之前,確保資料的型別是我們期望的。這有助於防止因型別錯誤而引發的執行時錯誤。

if val, ok := someInterface.(int); ok {
// someInterface 是一個int類型
fmt.Printf("Value is an int: %d\n", val)
} else {
// someInterface 不是一個int類型
fmt.Println("Value is not an int")
}

3. 在接口值中存儲額外信息

Type Assertions還可用於在interface中儲存額外的資料,這些資料只在特定類型時才可用。 以下程式碼使用Type Assertions 和 switch 來處理不同的struct

type Circle struct {
Radius float64
}

type Square struct {
SideLength float64
}
func printArea(shape interface{}) {
switch val := shape.(type) {
case Circle:
area := 3.14159265359 * val.Radius * val.Radius
fmt.Printf("Area of the circle: %f\n", area)
case Square:
area := val.SideLength * val.SideLength
fmt.Printf("Area of the square: %f\n", area)
default:
fmt.Println("Unknown shape")
}
}

Type Assertions 的實際應用

以下簡單介紹實際應用情況:

  1. JSON 解碼:當解碼 JSON 資料時,通常會解碼為 map[string]interface{} 或 []interface{},這些 interface 型別可以讓我們能夠動態處理資料,但有時我們需要將它們轉換為具體的 struct,以便更方便地使用。
package main

import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
jsonData := `{"Name": "Alice", "Age": 30}`
var data interface{}
err := json.Unmarshal([]byte(jsonData), &data)
if err != nil {
fmt.Println("JSON 解碼失敗:", err)
return
}
// 使用 Type Assertions 將介面型別轉換為結構體型別
if person, ok := data.(map[string]interface{}); ok {
name := person["Name"].(string)
age := int(person["Age"].(float64))
fmt.Printf("Name: %s, Age: %d\n", name, age)
} else {
fmt.Println("資料型別不是預期的 map[string]interface{}")
}
}

可以看到,我們首先解碼了一個 JSON 字串,並儲存在一個 interface 型別的變數 data 中。然後,我們使用 Type Assertions 將 data 斷言為 map[string]interface{} 型別,讓我們能夠訪問其中的字段。

2. 反射(Reflection): reflect 通常用於檢查和操作變數、struct 和 interface 型別的訊息。 在某些情況下,Type Assertions 在reflect 過程中經常派上用場,用於確認 interface 型別的實際內容。

package main

import (
"fmt"
"reflect"
)
func main() {
var x interface{} = 42
// 使用 Type Assertions 檢查實際型別
if val, ok := x.(int); ok {
fmt.Printf("x 是一個整數,值為:%d\n", val)
} else {
fmt.Println("x 不是一個整數")
}
// 使用 reflect 獲取型別信息
t := reflect.TypeOf(x)
fmt.Printf("x 的實際型別是:%s\n", t)
}

在這個範例中,我們首先使用 Type Assertions 檢查 x 的實際型別,然後使用 reflect 獲取型別信息。Type Assertions 確保了我們在確定型別後才能安全地訪問 val 變數。

Type Assertions 使用時的注意事項

在使用 Type Assertions 時,有些注意事項有助於確保程式碼如預期運作,並減少潛在的執行時錯誤。

  1. 始終檢查 ok 值:當進行 Type Assertions 時,無論如何都應該始終檢查 ok 值。這是確保轉換成功的關鍵。如果 ok 的值為 false,代表斷言失敗,你應該採取適當的錯誤處理措施,而不是假設轉換已成功。
  2. 使用 switch 語句:當處理多種可能的資料型別時,最好使用 switch 語句來進行 Type Assertions。這樣做的好處是,它使你的程式碼更具可讀性,並且更容易擴展。每個 case 子句可以處理一種特定的型別,讓程式邏輯清晰明瞭。
  3. 避免過多的 Type Assertions:過多的 Type Assertions 可能是程式設計上的警號,可能表示你的設計存在問題。儘量避免在程式碼中過多使用 Type Assertions,而是考慮使用 interface 和多態性來實現更優雅的設計。正確的 interface 設計可以減少對 Type Assertions 的需求,使程式碼更加簡潔且易於維護。

小結

Go 語言的 Type Assertions 讓我們能夠更好地處理不同資料型別的情況,同時保持程式的可讀性和安全性。無論是在處理 JSON 數據、實現 reflect 功能,Type Assertions 都是一個不可或缺的功能,有助於 Go 語言的應用程式開發更加靈活和強大。

📚Reference

avatar-img
17會員
83內容數
golang
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Alan的開發者天地 的其他內容
👨‍💻簡介 make函數在slice、map和之後會介紹到的channel的初始化中扮演著關鍵的角色。本文將會簡單介紹make函數的用法,以及在初始化不同資料結構時的差異,讓你更好地理解和利用make函數。
👨‍💻簡介 套件(Package)在Golang中扮演著組織和管理程式碼的重要角色。 package就像工具箱一樣,裡面裝滿各種不同的工具,每個工具都有特定的功能。這些工具能夠幫助你完成不同的任務,從修理家具到蓋小屋,樣樣都行。
👨‍💻簡介 在Go語言中,Interface 是一個重要且強大的概念。Interface提供了一種方式來定義對象之間的契約,讓你可以設計更具有靈活性和可擴展性的程式碼。 你可以把Interface想像成是一種約定,讓不同的東西彼此溝通的方式變得特別靈活和好擴充,告訴程式裡的各個元件彼此要怎麼合作
👨‍💻簡介 在程式開發的世界中,我們經常需要處理各式各樣的資料,可能是一個人的個人資訊,也可能是一個商品的詳細訊息。當我們面對這麼多的資料時,如何將它們有系統地整理起來,讓我們能夠輕鬆地找到所需,便成了一個重要的課題。這時,結構體的概念就像是一道曙光,為我們提供了一個非常有力的工具。 結
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
👨‍💻簡介 在 Go 語言中,有著一個強大又便捷的工具,可以讓你以鍵-值(Key-Value)的形式儲存和查詢資料,它就是「Map」。Map 在 Go 語言中扮演了重要的角色,簡化了許多資料處理的任務,現在讓我們一起來深入了解這個有趣的資料型別。 Map的基本概念 Map 是 Go 語
👨‍💻簡介 make函數在slice、map和之後會介紹到的channel的初始化中扮演著關鍵的角色。本文將會簡單介紹make函數的用法,以及在初始化不同資料結構時的差異,讓你更好地理解和利用make函數。
👨‍💻簡介 套件(Package)在Golang中扮演著組織和管理程式碼的重要角色。 package就像工具箱一樣,裡面裝滿各種不同的工具,每個工具都有特定的功能。這些工具能夠幫助你完成不同的任務,從修理家具到蓋小屋,樣樣都行。
👨‍💻簡介 在Go語言中,Interface 是一個重要且強大的概念。Interface提供了一種方式來定義對象之間的契約,讓你可以設計更具有靈活性和可擴展性的程式碼。 你可以把Interface想像成是一種約定,讓不同的東西彼此溝通的方式變得特別靈活和好擴充,告訴程式裡的各個元件彼此要怎麼合作
👨‍💻簡介 在程式開發的世界中,我們經常需要處理各式各樣的資料,可能是一個人的個人資訊,也可能是一個商品的詳細訊息。當我們面對這麼多的資料時,如何將它們有系統地整理起來,讓我們能夠輕鬆地找到所需,便成了一個重要的課題。這時,結構體的概念就像是一道曙光,為我們提供了一個非常有力的工具。 結
👨‍💻簡介 在 Go 語言中,函數(Function)是一個強大且重要的概念,就像食譜一樣,告訴你應該如何處理食材,最後得到一道美味的料理。經過哪些程序讓程式更有組織性和可讀性。函數可幫助你將程式碼區塊組織成可重複使用的元件,進而執行特定的任務。
👨‍💻簡介 在 Go 語言中,有著一個強大又便捷的工具,可以讓你以鍵-值(Key-Value)的形式儲存和查詢資料,它就是「Map」。Map 在 Go 語言中扮演了重要的角色,簡化了許多資料處理的任務,現在讓我們一起來深入了解這個有趣的資料型別。 Map的基本概念 Map 是 Go 語
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
中國電動車行業的持續發展受到了人們的廣泛討論,從對中國車的支持到反感,都有充分的論述。然而,需要釐清中國車企的品質問題,並對能代表中國車的車企進行更深入的討論。
Thumbnail
車庫娛樂邀約搶先看首映場 #夢行著保羅 劇情:已婚有二個女兒的大學教授保羅(尼可拉斯凱 飾)過著平凡且幸福的生活,但自從百萬名陌生人宣稱在夢中見到他,教授從平凡到受注目,最後被眾人嫌惡,變成別人的夢中人之後,這位教授的生活變得雞犬不寧…… 尼可拉斯凱不惜扮醜變禿頭男也想要演繹的電影,由原本的教授
Thumbnail
計畫和執行是兩件獨立的事 新的通路結構定案之後,有兩大執行重點必須照顧。新的秩序是全新通路結構預想的效果,沒有保證一定行得通。第二,若能從幾家老牌經銷商中間獲得幾家有識的公司,參與開發新的領域,對他們來說;會是很正面的生意發展機會。對我方而言,他們畢竟熟門熟路,對集團接下來的生意發展計劃會有事半功
Thumbnail
👨‍💻簡介 在Go中,假如我要判斷一個資料類型是甚麼,該怎麼做呢? Golang有一個功能叫做Type Assertions(類型斷言),它的作用就是能夠在運行時檢查我的資料類型,讓我在傳遞類型時能確保資料類型是正確的。
Thumbnail
導演馬庫斯羅森穆勒曾以結合戰爭歷史與古典音樂的《愛樂時光》廣獲好評,這次挑戰動作驚悚題材,再度交出一部劇力萬鈞的精彩作品。除了令人捏一把冷汗的刺激緊張情節,主角父女之間的真摯親情,也能令人深受感動,並為深陷困境的他們備感同情。
Thumbnail
律師律師,我創設了一個「開心致富」不公開社群,經嚴格審核後才能加入之會員制,每單位1萬美金,依照投資部位金額多寡給予每月2-5%的利潤,而且強調保本;我再拿這些投資人的資金去投資國內外股票、外匯、不動產、甚至虛擬貨幣,賺到的錢拿回來分潤給大家,這樣的模式雙方互利,有法律上問題嗎?
Thumbnail
點擊兩次滑鼠就可以下掛單、停止級別和預警。 將游標放在所需的價格級別上並從"圖表功能表"執行相應的命令。 根據游標位置不同,功能表中顯示的可用訂單類型也不同: 高於當前價格可下單Sell Limit和Buy Stop, 而低於當前價格則可下單Buy Limit和Sell Stop。 為從圖表創建的預
Thumbnail
您可以從“商品圖表”直接一鍵執行交易。這個選項在"交易"部分提供。 “商品圖表”中選擇的每個交易品種都提供一個單獨的交易面板。按一下Buy(買進)或Sell(賣出),平臺將立即下達相應訂單。 由於報價的變化,面板上的按鍵可能顯示不同的顏色: 如果當前價格高於之前價格,顯示為藍色。 如果當前價格低於之
Thumbnail
在金融交易中,速度至關重要。 此交易平臺提供了特殊的交易工具,可以一鍵執行交易,而無需設置額外的參數和做出其他確認。 請切換到“市場報價”的交易選項卡。 檢查清單: 在"市場報價"的交易部分執行交易 每個交易品種都提供一個單獨的交易面板。按一下Buy或Sell,平臺將立即下達相應訂單。 ------
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
中國電動車行業的持續發展受到了人們的廣泛討論,從對中國車的支持到反感,都有充分的論述。然而,需要釐清中國車企的品質問題,並對能代表中國車的車企進行更深入的討論。
Thumbnail
車庫娛樂邀約搶先看首映場 #夢行著保羅 劇情:已婚有二個女兒的大學教授保羅(尼可拉斯凱 飾)過著平凡且幸福的生活,但自從百萬名陌生人宣稱在夢中見到他,教授從平凡到受注目,最後被眾人嫌惡,變成別人的夢中人之後,這位教授的生活變得雞犬不寧…… 尼可拉斯凱不惜扮醜變禿頭男也想要演繹的電影,由原本的教授
Thumbnail
計畫和執行是兩件獨立的事 新的通路結構定案之後,有兩大執行重點必須照顧。新的秩序是全新通路結構預想的效果,沒有保證一定行得通。第二,若能從幾家老牌經銷商中間獲得幾家有識的公司,參與開發新的領域,對他們來說;會是很正面的生意發展機會。對我方而言,他們畢竟熟門熟路,對集團接下來的生意發展計劃會有事半功
Thumbnail
👨‍💻簡介 在Go中,假如我要判斷一個資料類型是甚麼,該怎麼做呢? Golang有一個功能叫做Type Assertions(類型斷言),它的作用就是能夠在運行時檢查我的資料類型,讓我在傳遞類型時能確保資料類型是正確的。
Thumbnail
導演馬庫斯羅森穆勒曾以結合戰爭歷史與古典音樂的《愛樂時光》廣獲好評,這次挑戰動作驚悚題材,再度交出一部劇力萬鈞的精彩作品。除了令人捏一把冷汗的刺激緊張情節,主角父女之間的真摯親情,也能令人深受感動,並為深陷困境的他們備感同情。
Thumbnail
律師律師,我創設了一個「開心致富」不公開社群,經嚴格審核後才能加入之會員制,每單位1萬美金,依照投資部位金額多寡給予每月2-5%的利潤,而且強調保本;我再拿這些投資人的資金去投資國內外股票、外匯、不動產、甚至虛擬貨幣,賺到的錢拿回來分潤給大家,這樣的模式雙方互利,有法律上問題嗎?
Thumbnail
點擊兩次滑鼠就可以下掛單、停止級別和預警。 將游標放在所需的價格級別上並從"圖表功能表"執行相應的命令。 根據游標位置不同,功能表中顯示的可用訂單類型也不同: 高於當前價格可下單Sell Limit和Buy Stop, 而低於當前價格則可下單Buy Limit和Sell Stop。 為從圖表創建的預
Thumbnail
您可以從“商品圖表”直接一鍵執行交易。這個選項在"交易"部分提供。 “商品圖表”中選擇的每個交易品種都提供一個單獨的交易面板。按一下Buy(買進)或Sell(賣出),平臺將立即下達相應訂單。 由於報價的變化,面板上的按鍵可能顯示不同的顏色: 如果當前價格高於之前價格,顯示為藍色。 如果當前價格低於之
Thumbnail
在金融交易中,速度至關重要。 此交易平臺提供了特殊的交易工具,可以一鍵執行交易,而無需設置額外的參數和做出其他確認。 請切換到“市場報價”的交易選項卡。 檢查清單: 在"市場報價"的交易部分執行交易 每個交易品種都提供一個單獨的交易面板。按一下Buy或Sell,平臺將立即下達相應訂單。 ------