Go 語言類型轉換的陷阱

1?

介紹

Go 語言作為強類型語言,在使用 Golang 開發項目時,經常會遇到類型轉換的場景,整型之間可以直接轉換,字節切片和字符串之間也可以直接轉換。

但是,如果整型和字符串之間做類型轉換,則需要使用?strconv?標準庫提供的函數。


2?

標準庫?strconv?類型轉換

Go 語言標準庫?strconv 提供了一些類型轉換的函數,比如在項目開發中使用比較多的整型和字符串之間的類型轉換。

func main() {salary := 5000salaryStr := strconv.Itoa(salary)fmt.Printf("%T salary=%d\n", salary, salary)fmt.Printf("%T salaryStr=%s\n", salaryStr, salaryStr)age := "23"ageInt, err := strconv.Atoi(age)fmt.Printf("%T age=%s\n", age, age)fmt.Printf("%T ageInt=%d err=%v\n", ageInt, ageInt, err)
}

輸出結果:

int salary=5000
string salaryStr=5000
string age=23
int ageInt=23 err=<nil>

閱讀上面這段代碼,我們使用標準庫?strconv?將整型變量?salary?轉換為字符串類型變量?salaryStr;將字符串類型變量?age?轉換為整型變量?ageInt

但是,讀者朋友們有沒有發現一個問題,我們使用標準庫?strconv?提供的函數?Atoi?將字符串類型變量轉換為整型變量,得到的是?int?類型,如果我們需要得到一個?int8?類型的變量,我們需要繼續做類型轉換,例如:

age := "23"
ageInt, err := strconv.Atoi(age)
ageInt8 := int8(ageInt)

也就是說,如果我們需要將一個字符串類型的變量轉換為一個非?int?類型的整型變量,需要做二次轉換,在實際項目開發中,使用起來稍微繁瑣一些。

此外,使用標準庫?strconv?做類型轉換,除了在一些場景中稍微繁瑣之外,還有另外一個問題,我們先閱讀以下一段代碼。

func main() {phoneNumber := "138001380001380013800013800138000"phoneNumberInt, err := strconv.Atoi(phoneNumber)fmt.Printf("%T phoneNumber=%s\n", phoneNumber, phoneNumber)fmt.Printf("%T phoneNumberInt=%d err=%v\n", phoneNumberInt, phoneNumberInt, err)
}

輸出結果:

string phoneNumber=138001380001380013800013800138000
int phoneNumberInt=9223372036854775807 err=strconv.Atoi: parsing "138001380001380013800013800138000": value out of range

閱讀上面這段代碼輸出的錯誤信息?value out of range,也就是說如果我們需要轉換的值超出返回,Go 語言標準庫?strconv?提供的函數?Atoi?會返回錯誤。

所以,在使用函數?Atoi?時,我們要做好參數驗證和錯誤處理。

有沒有使用更簡單的類型轉換庫,接下來,我們來看一下流行的三方庫?cast


3?

三方庫?cast?類型轉換

Go 類型轉換的三方庫?cast?是一個使用比較多的庫,我們使用?cast?來處理 Part02 的類型轉換需求,代碼如下:

func main() {age2 := "23"age2Int8 := cast.ToInt8(age2)fmt.Printf("%T age2=%s\n", age2, age2)fmt.Printf("%T age2Int8=%d\n", age2Int8, age2Int8)phoneNumber2 := "138001380001380013800013800138000"phoneNumber2Int := cast.ToInt(phoneNumber2)fmt.Printf("%T phoneNumber2=%s\n", phoneNumber2, phoneNumber2)fmt.Printf("%T phoneNumber2Int=%d\n", phoneNumber2Int, phoneNumber2Int)
}

輸出結果:

string?age2=23
int8?age2Int8=23
string?phoneNumber2=138001380001380013800013800138000
int?phoneNumber2Int=0

閱讀上面這段代碼,我們可以發現,使用?cast?可以直接將字符串類型的變量轉換為我們需要的整型變量,使用起來不再感到繁瑣。

同時,需要注意的是,如果轉換失敗,將返回類型零值,字符串類型變量?phoneNumber2?在使用?cast?轉換為?int?類型的變量時,返回的結果就是?int?的類型零值。

使用?cast?比使用?strconv?更簡單,而且不需要處理錯誤。但是,cast?還有一個陷阱,我們需要特別注意一下,我們先閱讀以下一段代碼:

func main() {month := "07"monthInt8 := cast.ToInt8(month)fmt.Printf("%T month=%s\n", month, month)fmt.Printf("%T monthInt8=%d\n", monthInt8, monthInt8)month2 := "08"month2Int8 := cast.ToInt8(month2)fmt.Printf("%T month2=%s\n", month2, month2)fmt.Printf("%T month2Int8=%d\n", month2Int8, month2Int8)
}

輸出結果:

string?month=07
int8?monthInt8=7
string?month2=08
int8?month2Int8=0

閱讀上面這段代碼的輸出結果,我們可以發現使用?cast?將字符串類型?month?和?month2?轉換為整型時,字符串是以?"0"?開頭的月份,"07"?轉換后得到整型?7,而?"08"?轉換后得到整型?0

我們再使用?strconv?轉換?"08",代碼如下:

func main() {month2 := "08"month2Int8 := cast.ToInt8(month2)fmt.Printf("%T month2=%s\n", month2, month2)fmt.Printf("%T month2Int8=%d\n", month2Int8, month2Int8)month2Int2, err := strconv.Atoi(month2)fmt.Printf("%T month2Int2=%d err=%v\n", month2Int2, month2Int2, err)
}

輸出結果:

int8?month2Int8=0
int?month2Int2=8?err=<nil>

讀者朋友們從輸出結果可以看到,"08"?使用?strconv?轉換后得到整型?8,所以我們在轉換以一個或多個?"0"?開頭的字符串為整型時,字符串?"0"?后面的數值大于?7?將不能使用?cast?轉換,最好就是在轉換以一個或多個?"0"?開頭的字符串為整型時,比如?"08""009""00010"?等,使用?strconv?轉換,而不要使用?cast?轉換。


4?

總結

本文我們介紹 Go 語言類型轉換的兩個庫,分別是標準庫?strconv?和三方庫?cast,其中?cast?更方便、更安全,但是也有陷阱,我們需要特別注意,避免在項目開發中掉進陷阱。

關于這兩個類型轉換庫的更多用法,感興趣的讀者朋友們可以熟讀手冊,多多動手練習。

參考資料:

strconv:?https://pkg.go.dev/strconv

cast:?https://github.com/spf13/cast

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35162.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35162.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35162.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.netcore grpc客戶端流方法詳解

一、客戶端流式處理概述 客戶端流式處理方法在該方法沒有接收消息的情況下啟動。 requestStream 參數用于從客戶端讀取消息。 返回響應消息時&#xff0c;客戶端流式處理調用完成。客戶端可以發送多個消息流到服務端&#xff0c;當所有客戶端消息流發送結束&#xff0c;調用請…

SpringBoot案例-部門管理-修改

目錄 前言 查看頁面原型&#xff0c;明確需求 頁面原型 需求 閱讀接口文件 思路分析 功能接口開發 控制層&#xff08;Controller類&#xff09; 業務層&#xff08;Service類&#xff09; 業務類 業務實現類 持久層&#xff08;Mapper類&#xff09; 接口測試 前…

Day 41

Day 41 343. 整數拆分 一個是j * dp[i - j]&#xff0c;相當于是拆分(i - j)&#xff0c;對這個拆分不理解的話&#xff0c;可以回想dp數組的定義。 dp[i] max({dp[i], (i - j) * j, dp[i - j] * j}); class Solution:def integerBreak(self, n: int) -> int:dp [0] *…

離線環境conda虛擬環境備份遷移--conda pack問題

1.第一步&#xff1a;創建虛擬環境 conda create -n pyenv --clone base 或者 conda create -n pyenv python3.8.5 --offline 命令執行結束&#xff0c;在路徑/xxxx/anaconda/envs 下看到pyenv 或者 conda info --envs 查看羅列虛擬環境 2.第二步&#xff1a;打包環境 conda …

ROS2 學習(一)介紹,環境搭建,以及個人安裝的一些建議

ROS2 學習 學習自b站課程&#xff1a;https://www.bilibili.com/video/BV16B4y1Q7jQ?p1 &#xff08;up主&#xff1a;古月居GYH&#xff09; ROS 介紹 Robot OS&#xff0c;為機器人開發提供了相對完善的 middleware&#xff0c;工具&#xff0c;軟件等。 ROS1 對嵌入式設…

計算機網絡(7) --- UDP協議和TCP協議

計算機網絡&#xff08;6&#xff09; --- https協議_哈里沃克的博客-CSDN博客https協議https://blog.csdn.net/m0_63488627/article/details/132112683?spm1001.2014.3001.5501 目錄 1.補充知識 1.PORT端口號 2.端口號范圍劃分 3.知名端口號 2.UDP協議 1.UDP報頭 2.U…

容器逃逸Docker cp(CVE-2019-14271)漏洞復現與分析

目錄 安裝 原理 EXP 參考 安裝 metarget安裝有點問題&#xff0c;所以我們直接指定安裝 可以用下面命令 查看包 apt-cache madison docker-ce 安裝 apt-get install -y docker-ce5:19.03.0~3-0~ubuntu-bionic 原理 EXP metarget/writeups_cnv/docker-cve-2019-14271 at …

Insert 1, Insert 2, Insert 3, ... 2023牛客暑期多校訓練營8 H

登錄—專業IT筆試面試備考平臺_牛客網 題目大意&#xff1a;給出一個長度為n的數組a&#xff0c;問有多少子串滿足其可以用多個排列穿插構成 1<n<1e6 思路&#xff1a;因為每個排列的起點都是1&#xff0c;所以我們大致的策略就是對于每一個1&#xff0c;記錄它往右最…

BGP小綜合

實驗題目如下&#xff1a; 實驗拓撲如下&#xff1a; 實驗要求如下&#xff1a; 【1】R2-7每臺路由器均存在一個環回接口用于建立鄰居&#xff0c;同時還存在一個環回來代表連接用戶的 接口;最終這些連接用戶的接口網絡需要可以和R1/8的環回通訊 【2】AS2網段地址1…

基于smardaten無代碼開發智能巡檢系統,讓無人機飛得更準

目錄 引言需求背景搭建思路開發過程&#xff08;1&#xff09;無人機設備數據接入&#xff08;2&#xff09;無人機巡檢任務管理&#xff08;3&#xff09;無人機三維防控監視&#xff08;4&#xff09;運防一體化大屏設計&#xff08;5&#xff09;異常告警管理&#xff08;6&…

面試總結-webpack/git

說說你對webpack的理解 webpack 是一個靜態模塊打包器&#xff0c;整個打包過程就像是一條生產線&#xff0c;把資源從入口放進去&#xff0c;經過一系列的加工&#xff08;loader&#xff09;&#xff0c;最終轉換成我們想要的結果&#xff0c;整個加工過程還會有監控&#x…

公共服務領域:西安新小區業主自立業主委員會年底分紅83萬以及103萬事件區塊鏈資金透明監管與投票解決方案的嘗試

公共服務領域:西安新小區業主自立業主委員會年底分紅83萬以及103萬事件區塊鏈資金透明監管與投票解決方案的嘗試 作者 重慶電子工程職業學院 | 向鍵雄 杜小敏 前言 本項目想法來源于,西安新小區業主開出物業自立業主委員會年底分紅83萬以及103萬事件,對于此類事件,我們刨…

微信小程序加載本地json和使用gulp壓縮js

加載本地json 創建json.js, data 里是json內容,exports 是數據出口 var data = [ {json1},{json2},{json3},{json10} ....] module.exports = {listData = data } 使用 這個require后面的參數是入口文件的文件路徑,但是注意必須是相對路徑,不能絕對路徑。 let json = re…

redis基礎(三十六)

安裝redis、配置redis 目錄 一、 概述 &#xff08;一&#xff09;NoSQL 1、類型 2、應用場景 &#xff08;二&#xff09;Redis 二、安裝 &#xff08;一&#xff09;編譯安裝 &#xff08;二&#xff09;RPM安裝 三、目錄結構 四、命令解析 五、redis登錄更改 1、…

2023國賽數學建模C題思路分析

文章目錄 0 賽題思路1 競賽信息2 競賽時間3 建模常見問題類型3.1 分類問題3.2 優化問題3.3 預測問題3.4 評價問題 4 建模資料 0 賽題思路 &#xff08;賽題出來以后第一時間在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 競賽信息 全國大學生數學建模…

中睿天下入選河南省網信系統2023年度網絡安全技術支撐單位

近日&#xff0c;河南省委網信辦發布了“河南省網信系統2023年度網絡安全技術支撐單位名單”&#xff0c;中睿天下憑借出色的網絡安全技術能力和優勢成功入選。 本次遴選由河南省委網信辦會同國家計算機網絡與信息安全管理中心河南分中心&#xff08;以下簡稱安全中心河南分中心…

持續輸出:自媒體持續輸出文字內容、視音頻創作(視頻課程、書籍章節)

以下是自媒體持續輸出文字內容、視音頻創作的最佳方法&#xff1a; 靈感來源&#xff1a;尋找靈感來源是自媒體創作的重要一環。可以從日常生活、網絡熱點、行業動態等方面尋找創作靈感。 確定主題&#xff1a;在確定主題的時候&#xff0c;需要根據讀者和觀眾的需求&#xff…

Zebec Protocol 將進軍尼泊爾市場,通過 Zebec Card 推動地區金融平等

流支付正在成為一種全新的支付形態&#xff0c;Zebec Protocol 作為流支付的主要推崇者&#xff0c;正在積極的推動該支付方案向更廣泛的應用場景拓展。目前&#xff0c;Zebec Protocol 成功的將流支付應用在薪酬支付領域&#xff0c;并通過收購 WageLink 將其納入旗下&#xf…

Pytest測試框架3

目錄&#xff1a; pytest結合數據驅動-yamlpytest結合數據驅動-excelpytest結合數據驅動-csvpytest結合數據驅動-jsonpytest測試用例生命周期管理&#xff08;一&#xff09;pytest測試用例生命周期管理&#xff08;二&#xff09;pytest測試用例生命周期管理&#xff08;三&a…

CMake 配置 Vulkan 出現鏈接失敗,找不到 vkEnumerateInstanceExtensionProperties 符號的錯誤的解決方法

使用 CMake 配置 glfw, glm 的時候&#xff0c;總是提示鏈接失敗&#xff0c;找不到 vkEnumerateInstanceExtensionProperties 符號 cmake_minimum_required(VERSION 3.4...3.27)if(${CMAKE_VERSION} VERSION_LESS 3.27)cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_…