『Go 內置庫第一季:strconv』

大家好,我叫謝偉,是一名程序員。

近期會持續更新內置庫的學習內容,主要的參考文獻是:godoc, 和源碼

日常編寫代碼的過程中,字符串和數值型、布爾類型之間的轉換算是很頻繁了。所以有必要研究下內置的 strconv 庫。

這節的主題是:字符串和其他基本數據類型之間的轉換。

除此之外,還有其他類型的轉換,最值得研究的就是 json , 這些內容,下期再講。

大綱:

  • 有哪些基本的數據類型
  • 自己總結的常用的API
  • 文檔給出的常用的API
  • 學到了什麼

有哪些基本的數據類型

  • 既然是字符串和其他基本數據類之間的轉換,那字符串可以操作的基本數據類型有哪些?
  • 字符串轉換爲其他數據類型的函數有什麼相似點?
  • 其他數據類型轉換爲字符串有什麼相似點?

怎麼知道這些答案?

  • 看文檔API
func Atoi(s string) (int, error)
func CanBackquote(s string) bool
func FormatBool(b bool) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func IsGraphic(r rune) bool
func IsPrint(r rune) bool
func Itoa(i int) string
func ParseBool(str string) (bool, error)
func ParseFloat(s string, bitSize int) (float64, error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (uint64, error)
  1. 大概可以得出答案:基本的數據類型指的是:布爾類型、數值型(整型、浮點型)
  2. 其他數據類型轉換爲字符串的函數多以:Format 爲關鍵字
  3. 字符串轉換爲其他數據類型的函數多以:Parse 爲關鍵字

自己常用的有哪些用法

  • 字符串轉整型: strconv.Atoi
func toInt(value string) (result int) {
    result, _ = strconv.Atoi(value)
    return

}

原理是:"abc" -- > a*100 + b*10 + c

  • 整型轉字符串: strconv.Itoa
func toString(value int) (result string) {
    result = strconv.Itoa(value)
    return
}
  • 字符串和布爾型之間的轉換
func toBool(value string) (result bool) {
    result, _ = strconv.ParseBool(value)
    return
}

func boolToString(value bool) (result string) {
    result = strconv.FormatBool(value)
    return
}
  • 字符串和浮點型數值之間的轉換
func toFloat(value string) (result float64) {
    result, _ = strconv.ParseFloat(value, 32)
    return
}

func floatToString(value float64) (result string) {
    result = strconv.FormatFloat(value, 'E', -1, 32)
    return
}

浮點數需要注意精度。

因爲數值存在進制的原因:所以需要熟悉這些概念:

  • base: 基準,進制 2,8,10,16
  • bitsize: 浮點類型 32,64

可以看出:

  • 字符串轉其他類型容易出錯,所以作者返回了 error, 關鍵字:Parse
  • 其他類型轉字符串,沒有錯誤處理, 關鍵字:Format

私以爲,掌握這些能處理絕大多數場景。

文檔給出的API

字符串和整型

func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func Atoi(s string) (i int, err error)
func toBaseInt(value string) (result int64) {
    result, _ = strconv.ParseInt("123", 8, 32)
    return
}

表示將 8 進制的 “123” 的字符串轉爲整型:1*8*8+2*8+3*1=83

所以可以將任意進制的數據轉換爲 整型,字符串轉成整型有錯誤處理,比如 7 進制的數“128” 出現 8, 那麼肯定報錯。

另外還存在無符號的數轉換

func IntToString(value int64) (result string) {
    return strconv.FormatInt(value, 8)
}

func main(){
    fmt.Println(IntToString(123))
}

>> 173

8 進制的 173 和 10 進制的 123 相等
1*64 + 7*8 + 3 = 64 + 56 + 3 = 123

總結這種轉換:

  • 注意進制
  • 注意精度

布爾和字符串

func ParseBool(str string) (value bool, err error)
func FormatBool(b bool) string

需要注意的是:

  • 布爾值不是隻 true 和 false, 表達式的值,比如 0<1 也表示false
  • 字符串的 true 和 false, 下面這種情況不行:FAlse, TRue, tRUE, fALSE , 所以要麼大寫,要麼小寫,要麼首字母大寫,要麼就單個字符,爲了避免出現這種情況,最好將字符串統一小寫或者大寫處理

浮點型和字符串

func ParseFloat(s string, bitSize int) (f float64, err error)
func FormatFloat(f float64, fmt byte, prec, bitSize int) string

可能會對 參數 fmt 有疑問,其實很好理解,fmt 格式化對浮點型有哪些操作?

%b      無小數部分的,指數爲二的冪的科學計數法,與 strconv.FormatFloat   
        的 'b' 轉換格式一致。例如 -123456p-78
%e      科學計數法,例如 -1234.456e+78                                  Printf("%e", 10.2)                          1.020000e+01
%E      科學計數法,例如 -1234.456E+78                                  Printf("%e", 10.2)                          1.020000E+01
%f      有小數點而無指數,例如 123.456                                 Printf("%f", 10.2)                          10.200000
%g      根據情況選擇 %e 或 %f 以產生更緊湊的(無末尾的0)輸出             Printf("%g", 10.20)                         10.2
%G      根據情況選擇 %E 或 %f 以產生更緊湊的(無末尾的0)輸出             Printf("%G", 10.20+2i)                      (10.2+2i)

其他

func Quote(s string) string
func QuoteRune(r rune) string
func QuoteRuneToASCII(r rune) string
func QuoteRuneToGraphic(r rune) string
func QuoteToASCII(s string) string
func QuoteToGraphic(s string) string

簡單來說,就是給加上引號, 適合雙引號或者單引號內的內容加引號。

學到了什麼

  • 錯誤處理

實現項目的中規範錯誤處理機制,比如錯誤碼的含義,具體顯示的信息之類的非常重要。

一般的項目中是如何處理的呢?

type ErrorCode struct{
    Code int
    Message string
}

func (e ErrorCode) Error()string{
    return fmt.Sprintf("Code: %d, Message: %s", e.Code, e.Message)
}


var Global strcut {
    ErrorRoute = ErrorCode{}
    ErrorDB = ErrorCode{}
    ...
}

看上去和 strconv 庫的錯誤處理機制類似:

  • 定義一個結構體
  • 實現 error 接口
type NumError struct {
    Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
    Num  string // the input
    Err  error  // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
}

func (e *NumError) Error() string {
    return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
}
  • 錯誤處理的兩者實現方式
errors.New()
fmt.Errorf()

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章