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

閱讀時間約 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

17會員
83內容數
golang
留言0
查看全部
發表第一個留言支持創作者!
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
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
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
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
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,平臺將立即下達相應訂單。 ------