1. 程式人生 > 程式設計 >Go 第三方庫之型別轉換問題

Go 第三方庫之型別轉換問題

目錄
  • 01 為什麼需要型別轉換
  • 02 spf13/cast
    • 1)To_ 形式函式
    • 2)To_E 形式函式
  • 03 總結

    強型別語言有它的優勢,但也有不便利的地方,最典型的就是型別轉換。 作為一門強型別語言,而且不支援隱式型別轉換,因此這個問題更突出。雖然 Go 提供了不少方式進行型別轉換,包括相關的標準庫,比如 strconv 包。

    然而,strconv 包使用沒那麼方便,比如 "8" 轉為 int 型別:

    s := "8"
    i,err := strconv.Atoi(s)

    你必須對 err 進行處理,因為返回兩個值,沒法直接將結果傳遞給接收 int 引數的函式,使用不方便。

    今天給大家介紹一個第三方庫,專門處理型別轉換的問題。

    01 為什麼需要型別轉換

    有一些場景會需要使用型別轉換:

    從 yaml、toml、on 等配置檔案中讀取資料;
    從網路接收請求資料;
    其他通過 interface{} 處理資料的情況;
    。。。
    轉換為正確的型別,能充分利用強型別的好處,讓程式更健壯、更安全。

    02 spf13/cast

    第三方包 .com/spf13/cast 專門解決型別轉換的問題,這個包產生於 hugo。當時主要用於處理 yaml 等配置檔案資料的轉換。該包不會 panic。

    該包目前有 1.6k+ 的 Star,有超過 4000 多個開源專案使用了該包。

    這個包使用很簡單,主要有兩套函式:

    1)To_ 形式函式

    這些函式始終返回所需的型別。如果無法正確轉換為對應的型別,則返回目標型別的零值。

    支援的型別包括所有的基本資料型別,還支援 time.Time、time.Duration、slice、map 等常用型別。

    比如:

    cast.ToString("mayonegg")         // "mayonegg"
    cast.ToString(8)                  // "8"
    cast.ToString(8.31)               // "8.31"
    cast.ToString([]byte("one tihttp://www.cppcns.comme")) // "one time"
    cast.ToString(nil)                // ""
    cast.ToTime("2021-08-10 22:00:00") // 2021-08-10 22:00:00 +0000 UTC

    注意,轉換為 time.Time 時,需要注意時區問題。ToTime 預設使用 UTC,如果想用其他時區,得類似這麼做:

    secondsEastOfUTC := int((8 * time.Hour).Seconds())
    beijing := time.FixedZone("Beijing Time",secondsEastOfUTC)
    fmt.Println(cast.ToTimeInDefaultLocation("2021-08-10 22:00:00",beijing))

    當然,你也可以這樣:

    fmt.Println(cast.ToTimeIwww.cppcns.comnDefaultLocation("2021-08-10 22:00:00",time.Lhttp://www.cppcns.comocal))

    不過,Local 表示本地時區,要明確這個本地是不是你想要的。

    2)To_E 形式函式

    E 表示 error,也就是說,這一系列函式會返回 error。在無法進行型別轉換時,會將錯誤原因返回。To_ 形式內部呼叫的是 To_E 形似,只是它忽略了錯誤。

    這種形式就不舉例了。一般地,除非你需要區分零值是因為出錯導致的還是本身就是零值,否則應該使用 To_ 系列函式,畢竟更省事。

    03 總結

    大概率,不少公司都有自己類似的庫。如果沒有,可以考慮使用該庫,這樣的輪子,沒太多必要造。不過這個庫有一點我不太喜歡,就是沒法指定預設值。

    比如,我想在轉換失敗時,返回我的預設值,而不是預設零值,這個包做不到。常見的場景就是,處理使用者可選輸入,如果使用者沒輸入,給一個預設值。

    配置檔案也有這樣的場景,比如某個配置項如果沒有配置,我希望硬編碼一個預設值。因為 cast 不支援,依賴 cast 的 github.com/spf13/viper 庫也不支援預設值,導致我會寫出這樣的繁瑣程式碼:

    viper.SetDefault("listen.port","2021")
    port := viper.GetString("listen.port")

    我更希望的是這樣的程式碼:

    port := viper.GetString("listen.port","2021") // listen.port 沒設定時,返回 2021

    到此這篇關於Go 第三方庫之型別轉換問題的文章就介紹到這了,更多相關Go 第三方庫型別轉換內容請搜尋我們以前的文章或繼續WLoat瀏覽下面的相關文章希望大家以後多多支援我們!