欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你了解Golang中類型轉(zhuǎn)換庫(kù)cast的使用

 更新時(shí)間:2023年02月08日 08:49:49   作者:程序員小杜  
你是否在使用 Go 的過(guò)程中因?yàn)轭愋娃D(zhuǎn)換的繁瑣而苦惱過(guò)?你是否覺(jué)得 Go 語(yǔ)言中的類型斷言可能會(huì) panic 而對(duì)自己寫(xiě)的代碼有那么一點(diǎn)點(diǎn)不放心?本文就為大家推薦一個(gè)用于類型轉(zhuǎn)換的第三方庫(kù) cast 絕對(duì)是一個(gè)值得嘗試的選擇

0 前言

你是否在使用 Go 的過(guò)程中因?yàn)轭愋娃D(zhuǎn)換的繁瑣而苦惱過(guò)?

你是否覺(jué)得 Go 語(yǔ)言中的類型斷言可能會(huì) panic 而對(duì)自己寫(xiě)的代碼有那么一點(diǎn)點(diǎn)不放心?

如果你有過(guò)如上體驗(yàn),并且想要找到一個(gè)合適的解決方案的話,那么本文推薦的一個(gè)用于類型轉(zhuǎn)換的第三方庫(kù) cast 絕對(duì)是一個(gè)值得嘗試的選擇。

1 cast

cast 是一個(gè)極為簡(jiǎn)潔的第三方庫(kù),github 地址:https://github.com/spf13/cast。

項(xiàng)目主頁(yè)里的頭兩句介紹就是:

Easy and safe casting from one type to another in Go

Don’t Panic! ... Cast

可見(jiàn),cast 的主要功能就是類型轉(zhuǎn)換,且沒(méi)有 panic。

多說(shuō)一句,Don't panic 在英語(yǔ)中本身就是一個(gè)常用語(yǔ),表示不要慌張、不要害怕,所以,在這里其實(shí)是一個(gè)有意思的雙關(guān)。

2 上手

2.1 安裝引入

這里只講 go mod 的引入方式。

在 go.mod 文件中 require github.com/spf13/cast v1.5.0(目前最新版為 1.5.0),接著用 mod 進(jìn)行 download、tidy 等操作,再在代碼中 import "github.com/spf13/cast" 即可使用 cast 關(guān)鍵字使用 cast 的功能了。

2.2 使用

2.2.1 常規(guī)用法

我們直接通過(guò)幾個(gè)簡(jiǎn)單的例子來(lái)體驗(yàn)一下 cast:

var target interface{} = "123"
str := "hello, world!"

fmt.Println(cast.ToString(target))
fmt.Println(cast.ToInt(target))
fmt.Println(cast.ToInt(str))

// 輸出:
123
123
0

我們創(chuàng)建了一個(gè) interface{} 類型的變量 target,傳統(tǒng)方式下如果要將一個(gè) interface{} 轉(zhuǎn)化為 string,需要使用類型斷言:

var target interface{} = "123"

str := target.(string)
// or
str, ok := target.(string)

類型斷言的缺點(diǎn)很明顯,如果不接收第二個(gè)返回值,會(huì)有 panic 風(fēng)險(xiǎn);如果接收第二個(gè)參數(shù),則略顯繁瑣。

到了第二個(gè) ToInt,cast 的優(yōu)勢(shì)就更明顯了,傳統(tǒng)方式下,一個(gè) interface{} 類型的 "123" 如果要轉(zhuǎn)換成 int,必須先類型斷言為 string,再使用 strconv 轉(zhuǎn)換成 int,代碼就不寫(xiě)了,想象一下就知道有多麻煩,而 cast 可以將這個(gè)過(guò)程一步到位。

接著是第三個(gè)輸出 cast.ToInt(str),這里的 str 是一個(gè) string 類型的 "hello, world!",它顯然不能被轉(zhuǎn)換成 int,于是 cast 將其設(shè)置為 int 的零值 0

其實(shí) cast 的所有類型轉(zhuǎn)換都會(huì)將無(wú)法轉(zhuǎn)換的結(jié)果轉(zhuǎn)為零值,而不是 panic,這也就是 cast 官方承諾的 Don't panic。

2.2.2 帶 error 的用法

看到這里,有朋友可能要問(wèn)了:如果我的邏輯必須判斷目標(biāo)是否轉(zhuǎn)換成功了呢?如果我的轉(zhuǎn)換結(jié)果就有可能是 0 呢?我怎么知道這個(gè) 0 是轉(zhuǎn)換失敗的零值,還是目標(biāo)原始的真實(shí)值?

cast 的作者自然也想到了這一點(diǎn),于是,cast 的所有類型轉(zhuǎn)換函數(shù)都有一個(gè)對(duì)應(yīng)的 with error 版:

str := "hello"
strNum := "123"

num, e := cast.ToIntE(str)
fmt.Println(num)
fmt.Println(e)

num, e = cast.ToIntE(strNum )
fmt.Println(num)
fmt.Println(e)

// 輸出
0
unable to cast "hello" of type string to int64
123
nil

帶 error 的版本其實(shí)就是在非 error 版的函數(shù)名結(jié)尾添加了一個(gè) E,其結(jié)果也很好理解,這里不再展開(kāi)細(xì)講了。

2.2.3 很酷的東西

最后再來(lái)看一個(gè)我覺(jué)得很酷的東西:

var js interface{} = `{"name": "Jack", "gender": "male"}`

fmt.Println(cast.ToStringMap(js))

// 輸出
map[gender:male name:Jack]

cast 能直接將一個(gè) JSON 字符串轉(zhuǎn)換成 map!當(dāng)然這一步其實(shí)用類型斷言也可以做到,但 cast 的方式會(huì)更加優(yōu)雅。

3 性能及原理

如果你只是想使用 cast,那么接下來(lái)的內(nèi)容就可以忽略了;如果你還想深入了解一些 cast,可以看看這一節(jié)。

很多做后端開(kāi)發(fā)的朋友會(huì)習(xí)慣性關(guān)心性能和原理,我也一樣,所以早在我第一次接觸使用 cast 時(shí),我就去看了它的源碼,然后……這樣,我直接把上面我們用過(guò)的 ToInt 的相關(guān)源碼列出來(lái),大家自己看看就明白了:

// cast.go

// ToInt casts an interface to an int type.
func ToInt(i interface{}) int {
    v, _ := ToIntE(i)
    return v
}

// caste.go

// ToIntE casts an interface to an int type.
func ToIntE(i interface{}) (int, error) {
    i = indirect(i)    // 這個(gè) indirect 函數(shù)里使用反射來(lái)獲取 i 的 interface{} 值,代碼不列了
    // ...省略
    switch s := i.(type) {
    case int64:
        return int(s), nil
    case int32:
        return int(s), nil
    // ...省略
    case string:
        v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
        if err == nil {
            return int(v), nil
        }
        return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
    }
    // ...省略
}

明白了吧,沒(méi)有什么技巧,依然是常規(guī)手段進(jìn)行轉(zhuǎn)換,只是它把各種情況都囊括了進(jìn)來(lái),做到了足夠全面。

而且我們發(fā)現(xiàn),帶 error 的函數(shù)才是原始函數(shù),不帶 error 的只是一個(gè)封裝后的便捷方式。

cast 的源碼很短,只有兩個(gè)文件,加起來(lái)不到 2000 行。

所以看到這里,cast 的性能問(wèn)題就沒(méi)什么值得討論的了,一定高不到哪兒去。尤其在泛型已經(jīng)實(shí)裝了之后,泛型的性能要遠(yuǎn)超類型斷言、反射之類的技術(shù),因此大家在使用 cast 的時(shí)候也請(qǐng)視情況而定。

4 總結(jié)

cast 是我用了很多年的一個(gè)庫(kù)了,早在泛型還八字沒(méi)一撇的時(shí)候我就發(fā)現(xiàn)了這個(gè)庫(kù),那時(shí)我們的項(xiàng)目代碼里充斥著許多 interface{} 和反射,cast 的確幫了我們很大的忙。盡管現(xiàn)在已經(jīng)是泛型時(shí)代,go 語(yǔ)言可以用性能更佳的泛型替代許多以前只能用 interface{} 甚至反射實(shí)現(xiàn)的場(chǎng)景,但依然存在不少我們無(wú)法避免要用 interface{} 或類型轉(zhuǎn)換的地方,這種時(shí)候,尤其是這段程序?qū)π阅懿幻舾袝r(shí),cast 依然是一把萬(wàn)金油式的利器。

總結(jié)一下,cast 是一個(gè)用于類型轉(zhuǎn)換的 golang 第三方庫(kù),它最大的特點(diǎn)是在類型轉(zhuǎn)換時(shí)可以不 panic,而是將出現(xiàn)問(wèn)題的地方轉(zhuǎn)換成零值。當(dāng)然,cast 也提供了帶 error 的函數(shù),以供開(kāi)發(fā)者在適當(dāng)情況下使用。cast 的性能可能會(huì)是一個(gè)問(wèn)題,因此我們?cè)谑褂脮r(shí)一定要選擇合適的場(chǎng)景,避免由于濫用 cast 造成的性能瓶頸。

到此這篇關(guān)于一文帶你了解Golang中類型轉(zhuǎn)換庫(kù)cast的使用的文章就介紹到這了,更多相關(guān)Golang類型轉(zhuǎn)換庫(kù)cast內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解簡(jiǎn)單高效的Go?struct優(yōu)化

    詳解簡(jiǎn)單高效的Go?struct優(yōu)化

    這篇文章主要為大家介紹了簡(jiǎn)單高效的Go?struct優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Go語(yǔ)言中的字符串處理方法示例詳解

    Go語(yǔ)言中的字符串處理方法示例詳解

    Go語(yǔ)言的字符串是使用UTF-8編碼的。UTF-8是Unicode的實(shí)現(xiàn)方式之一。這篇文章主要介紹了Go語(yǔ)言中的字符串處理方法,需要的朋友可以參考下
    2018-10-10
  • 詳解Go語(yǔ)言如何判斷兩個(gè)對(duì)象是否相等

    詳解Go語(yǔ)言如何判斷兩個(gè)對(duì)象是否相等

    在編程中,判斷兩個(gè)對(duì)象是否相等是一項(xiàng)常見(jiàn)的任務(wù),同時(shí)判斷對(duì)象是否相等在很多情況下都非常重要,所以在接下來(lái)的內(nèi)容中,我們將詳細(xì)介紹在?Go?語(yǔ)言中如何判斷對(duì)象是否相等的方法和技巧,需要的可以參考一下
    2023-06-06
  • 一文帶你了解Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)strings的常用函數(shù)和方法

    一文帶你了解Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)strings的常用函數(shù)和方法

    strings?庫(kù)包含了許多高效的字符串常用操作的函數(shù)和方法,巧用這些函數(shù)與方法,能極大的提高我們程序的性能。本文就來(lái)和大家分享一下Go標(biāo)準(zhǔn)庫(kù)strings的常用函數(shù)和方法,希望對(duì)大家有所幫助
    2022-11-11
  • golang使用viper解析配置文件的示例代碼

    golang使用viper解析配置文件的示例代碼

    Viper是一個(gè)輕量級(jí)的、易于使用的配置工具庫(kù),它允許你在Go應(yīng)用中方便地管理配置,Viper支持從多種來(lái)源讀取配置,如環(huán)境變量、命令行參數(shù)、文件、甚至是加密的數(shù)據(jù)存儲(chǔ),本文給大家介紹了golang使用viper解析配置文件,需要的朋友可以參考下
    2024-08-08
  • Go語(yǔ)言字符串處理庫(kù)strings包詳解

    Go語(yǔ)言字符串處理庫(kù)strings包詳解

    本文詳細(xì)介紹了Go語(yǔ)言中的strings庫(kù)的使用方法,包括字符串的查找、替換、分割、比較、大小寫(xiě)轉(zhuǎn)換等操作,strings庫(kù)是Go語(yǔ)言中非常重要且功能豐富的標(biāo)準(zhǔn)庫(kù),幾乎涵蓋了所有字符串處理的需求
    2024-09-09
  • Go語(yǔ)言string,int,int64 ,float之間類型轉(zhuǎn)換方法

    Go語(yǔ)言string,int,int64 ,float之間類型轉(zhuǎn)換方法

    Go語(yǔ)言中int類型和string類型都是屬于基本數(shù)據(jù)類型,兩種類型的轉(zhuǎn)化都非常簡(jiǎn)單。下面通過(guò)本文給大家分享Go語(yǔ)言string,int,int64 ,float之間類型轉(zhuǎn)換方法,感興趣的朋友一起看看吧
    2017-07-07
  • GO語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程圖文詳解

    GO語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程圖文詳解

    這篇文章主要介紹了GO語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程圖文詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Go語(yǔ)言sync.Cond基本使用及原理示例詳解

    Go語(yǔ)言sync.Cond基本使用及原理示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言sync.Cond基本使用及原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 一文詳解Go Http Server原理

    一文詳解Go Http Server原理

    這篇文章主要為大家介紹了Go Http Server原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論