如何在 Go 中轉換數據類型

介紹

在 Go 中,數據類型用於對一種特定類型的數據進行分類,確定可以分配給該類型的值以及可以對其執行的操作。在編程時,有時你需要在類型之間轉換值以便以不同的方式操作值。例如,你可能需要將數值與字符串連接起來,或者在初始化爲整數值的數字中表示小數位。用戶生成的數據通常會自動分配爲字符串數據類型,即使它由數字組成;爲了在此輸入中執行數學運算,你必須將字符串轉換爲數字數據類型。

由於 Go 是一種靜態類型語言,數據類型綁定到變量 而不是值。這意味着,如果你將變量定義爲 int,它只能是 int;如果不轉換變量的數據類型,就無法將一個 字符串 賦值給它。Go 中數據類型的靜態特性使得學習轉換它們的方法更加重要。

本教程將指導你完成數字和字符串的轉換,並提供示例以幫助你熟悉不同的用例。

數字類型轉換

Go 有多種數字類型可供選擇。它們主要分爲兩種類型:integers 和 floating-point numbers

在許多情況下,你可能希望在數字類型之間進行轉換。在 ‍不‍同大小的數字類型 之間進行轉換有助於優化特定場景下的性能。如果你有來自代碼另一部分的整數並想要對其進行除法,你可能需要將整數轉換爲浮點數以保持操作的精度。此外,時間相關的操作通常涉及整數轉換。爲了解決這些情況,Go 爲大多數數字類型提供了內置的_類型轉換_。

整數類型之間的轉換

Go 有許多整數數據類型可供選擇。何時使用另一種通常更多要考慮的是 性能;但是,有時你需要從一種整數類型轉換爲另一種整數類型。例如,Go 有時會自動生成數值爲 int,這可能與你的輸入值不匹配。如果你的輸入值爲 int64,則在將它們的數據類型轉換爲匹配之前,你將無法在同一數學表達式中使用 intint64

假設你有一個 int8 並且需要將其轉換爲 int32。你可以通過 int32() 類型轉換來做到這一點:

var index int8 = 15

var bigIndex int32

bigIndex = int32(index)

fmt.Println(bigIndex)
Output
15

此代碼塊將 index 定義爲 int8 數據類型,將 bigIndex 定義爲 int32 數據類型。要將 index 的值存儲在 bigIndex 中,它將數據類型轉換爲 int32。這是通過 int32() 包裝 index 變量來完成的。

要驗證你的數據類型,你可以使用 fmt.Printf 語句和 %T ,語法如下:

fmt.Printf("index data type:    %T\n", index)
fmt.Printf("bigIndex data type: %T\n", bigIndex)
Output
index data type:    int8
bigIndex data type: int32

由於使用了 %T ,打印語句會輸出變量的類型,而不是變量的實際值。這樣,你可以確認轉換後的數據類型。

你還可以從較大整數類型轉換爲較小整數類型:

var big int64 = 64

var little int8

little = int8(big)

fmt.Println(little)
Output
64

Keep in mind that when converting integers you could potentially exceed the maximum value of the data type and wraparound: 請記住,在轉換整數時,你可能會超過數據類型的最大值和 wraparound

var big int64 = 129
var little = int8(big)
fmt.Println(little)
Output
-127

當值轉換爲太小而無法容納它的數據類型時,就會發生出。在前面的示例中,8 位的數據類型 int8 沒有足夠的空間來容納 64 位的變量 big 。從較大數據類型轉換爲較小數據類型時應始終小心,以免意外截斷數據。

將整數轉換爲浮點數

在 Go 中將整數轉換爲浮點數類似於將一種整數類型轉換爲另一種。你可以通過給要轉換的整數包裝 float64()float32() 來使用內置類型轉換:

var x int64 = 57

var y float64 = float64(x)

fmt.Printf("%.2f\n", y)
Output
57.00

這段代碼聲明瞭一個類型爲 int64 的變量 x 並將其值初始化爲 57

var x int64 = 57

x 使用 float64() 會將 57 轉換爲 57.00 的浮點值。

var y float64 = float64(x)

%.2f 告訴 fmt.Printf 用兩位小數格式化浮點數。

你也可以對變量這麼操作。以下代碼將 f 聲明爲 57,然後打印出新的浮點數:

var f float64 = 57
fmt.Printf("%.2f\n", f)
Output
57.00

通過使用 float32()float64(),你可以將整數轉換爲浮點數。接下來,你將學習如何將浮點數轉換爲整數。

將浮點數轉換爲整數

Go 可以將浮點數轉換爲整數,但程序會丟失浮點數的精度。

使用 int() 或其他非浮點數據類型包裝浮點數,其工作方式與整數類型轉換類似。你可以在括號內添加一個浮點數以將其轉換爲整數:

var f float64 = 390.8
var i int = int(f)

fmt.Printf("f = %.2f\n", f)
fmt.Printf("i = %d\n", i)
Output
f = 390.80
i = 390

此語法會將浮點數 390.8 轉換爲整數 390,去掉小數位。

你也可以將其與變量一起使用。以下代碼聲明 b 等於 125.0c 等於 390.8,然後將它們打印爲整數。短變量聲明(:=)縮短了語法:

b := 125.0
c := 390.8

fmt.Println(int(b))
fmt.Println(int(c))
Output
125
390

當使用 int() 類型將浮點數轉換爲整數時,Go 會截斷浮點數的小數並保留剩餘數字部分來創建整數。請注意,即使你可能希望將 390.8 向上取整到 391,Go 也不會通過 int() 類型執行此操作。相反,它會去掉小數點。

除法中的類型轉換

在 Go 中除以整數類型時,結果也將是整數類型,去掉了 模數 或餘數:

a := 5 / 2
fmt.Println(a)
Output
2

在做除法操作時,如果有數字類型是浮點數的話,那麼所有類型都將自動聲明爲浮點數:

 a := 5.0 / 2
 fmt.Println(a)
Output
2.5

上例將浮點數 5.0 除以整數 2 ,答案 2.5 是一個保留小數精度的浮點數。

在本節中,你已經在不同的數字數據類型之間進行了轉換,包括不同大小的整數和浮點數。接下來,你將學習如何在數字和字符串之間進行轉換。

字符串轉換

字符串 是一個或多個字符(字母、數字或符號)組成的序列。字符串是計算機程序中一種常見的數據形式,你可能需要經常將字符串轉換爲數字或將數字轉換爲字符串,尤其是在你接收用戶生成的數據時。

將數字轉換爲字符串

你可以使用 Go 標準庫中 strconv 包中的 strconv.Itoa 方法將數字轉換爲字符串。如果將數字或變量傳遞給該方法,則該數字值將被轉換爲字符串。

首先,讓我們看看轉換整數。要將整數 12 轉換爲字符串,可以將 12 傳遞給 strconv.Itoa 方法:

package main

import (
 "fmt"
 "strconv"
)

func main() {
 a := strconv.Itoa(12)
 fmt.Printf("%q\n", a)
}

運行此程序時,你將收到以下輸出:

Output
"12"

數字 12 周圍的引號表示該數字不再是整數,而是字符串。

你使用 := 賦值運算符來聲明一個名爲 a 的新變量,並將 strconv.Itoa() 函數返回的值賦值給它。此時值 12 被分配給了變量。你通過在 fmt.Printf 函數中使用 %q 來告訴函數引用提供的字符串參數。

通過使用變量,你更能瞭解將整數轉換爲字符串的實際情況。假設你想跟蹤用戶的日常編程進度,並輸入他們一次編寫的代碼行數。你希望將此反饋顯示給用戶,並將同時打印出字符串和整數值:

package main

import (
 "fmt"
)

func main() {
 user := "Sammy"
 lines := 50

 fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
}

運行此代碼時,你將收到以下錯誤:

Output
invalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int)

你不能在 Go 中拼接字符串和整數,所以你必須將變量 lines 轉換爲字符串:

package main

import (
 "fmt"
 "strconv"
)

func main() {
 user := "Sammy"
 lines := 50

 fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.")
}

現在,當你運行代碼時,你將收到以下輸出,祝賀你的用戶取得了進展:

Output
Congratulations, Sammy! You just wrote 50 lines of code.

如果你希望將浮點數轉換爲字符串而不是將整數轉換爲字符串,請遵循類似的步驟和格式。當你將浮點數傳遞給 fmt.Sprint 方法時,從 Go 標準庫中的 fmt 包中,將返回浮點數的字符串值。你可以使用浮點值本身或變量:

package main

import (
 "fmt"
)

func main() {
 fmt.Println(fmt.Sprint(421.034))

 f := 5524.53
 fmt.Println(fmt.Sprint(f))
}
Output
421.034
5524.53

你可以通過拼接字符串來測試以確保它是正確的:

package main

import (
 "fmt"
)

func main() {
 f := 5524.53
 fmt.Println("Sammy has " + fmt.Sprint(f) + " points.")
}
Output
Sammy has 5524.53 points.

你可以確定你的浮點數已正確轉換爲字符串,因爲拼接執行時沒有報錯。

將字符串轉換爲數字

可以使用 Go 標準庫中的 strconv 包將字符串轉換爲數字。strconv 包具有轉換整數和浮點數類型的功能。這是接受用戶輸入時非常常見的操作。例如,如果你有一個程序詢問一個人的年齡,當他們輸入值時,它會被捕獲爲 字符串 。然後,你需要將其轉換爲 int 以對其進行任何數學運算。

如果你的字符串沒有小數位,你很可能希望使用 strconv.Atoi 函數將其轉換爲整數。如果你知道你將使用數字作爲浮點數,你會使用strconv.ParseFloat

讓我們使用用戶 Sammy 跟蹤每天編寫的代碼行的示例。你可能希望使用運算符來操作這些值,以便爲用戶提供更有趣的反饋,但這些值當前存儲在字符串中:

package main

import (
 "fmt"
)

func main() {
 lines_yesterday := "50"
 lines_today := "108"

 lines_more := lines_today - lines_yesterday

 fmt.Println(lines_more)
}
Output
invalid operation: lines_today - lines_yesterday (operator - not defined on string)

因爲這兩個數值存儲在字符串中,所以你收到報錯。減法運算符 - 不能對兩個字符串執行。

修改代碼來增加 strconv.Atoi() 方法,該方法能將字符串轉換爲整數,這將允許你對最初是字符串的值進行數學運算。因爲在將字符串轉換爲整數時可能會失敗,所以你必須檢查是否有任何報錯。你可以使用 if 語句來檢查你的轉換是否成功。

package main

import (
 "fmt"
 "log"
 "strconv"
)

func main() {
 lines_yesterday := "50"
 lines_today := "108"

 yesterday, err := strconv.Atoi(lines_yesterday)
 if err != nil {
  log.Fatal(err)
 }

 today, err := strconv.Atoi(lines_today)
 if err != nil {
  log.Fatal(err)
 }
 lines_more := today - yesterday

 fmt.Println(lines_more)
}

因爲字符串可能不是數字,所以 strconv.Atoi() 方法將返回轉換後的類型以及潛在的錯誤。當使用 strconv.Atoi 函數從 lines_yesterday 轉換時,你必須檢查 err 返回值以確保該值已被轉換。如果 err 不是 nil,則意味着 strconv.Atoi 無法成功將字符串值轉換爲整數。在這個例子中,你使用了一個 if 語句來檢查錯誤,如果返回了一個錯誤,你使用了 log.Fatal 來記錄錯誤並退出程序。

當你運行前面的代碼時,你會得到:

Output
58

現在嘗試轉換一個不是數字的字符串:

package main

import (
 "fmt"
 "strconv"
)

func main() {
 a := "not a number"
 b, err := strconv.Atoi(a)
 fmt.Println(b)
 fmt.Println(err)
}

你將收到以下報錯:

Output
0
strconv.Atoi: parsing "not a number": invalid syntax

因爲聲明瞭 b,但 strconv.Atoi 未能進行轉換,所以 b 沒能被賦值。請注意,b 的值爲 0 。這是因爲 Go 有默認值,在 Go 中稱爲零值。strconv.Atoi 返回了一個錯誤,描述了爲什麼它無法轉換字符串。

轉換字符串和字節

Go 中的字符串存儲爲字節切片。在 Go 中,你可以通過將其包裝在 []byte()string() 的相應轉換中來在字節切片和字符串之間進行轉換:

package main

import (
 "fmt"
)

func main() {
 a := "my string"

 b := []byte(a)

 c := string(b)

 fmt.Println(a)

 fmt.Println(b)

 fmt.Println(c)
}

在這裏,你將字符串存儲在 a 中,然後將其轉換爲字節切片b,然後將字節切片轉換回字符串並賦值給c。最後打印出來:

Output
my string
[109 121 32 115 116 114 105 110 103]
my string

輸出的第一行是原始字符串 my string。打印出來的第二行是組成原始字符串的字節切片。第三行顯示字節切片可以安全地轉換回字符串並打印出來。

結論

本 Go 教程主要演示瞭如何通過內置方法將幾種重要的數據類型轉換爲其他數據類型。能夠在 Go 中轉換數據類型將允許你執行諸如接受用戶輸入和跨不同數字類型進行數學運算之類的事情。稍後,當你使用 Go 編寫接受來自許多不同來源(如數據庫和 API)的數據的程序時,你將使用這些轉換方法來確保你可以對數據進行操作。你還可以通過將數據轉換爲更小的數據類型來優化存儲。

如果你想深入分析 Go 中的數據類型,請查看我們的 《理解 Go 中的數據類型》 relref "/docs/07-Understanding_Data_Types_in_Go.md" >}}) 文章。

數據類型綁定到變量:

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E5%A3%B0%E6%98%8E%E5%8F%98%E9%87%8F%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B

integers

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E6%95%B4%E6%95%B0

floating-point numbers:

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E6%B5%AE%E7%82%B9%E6%95%B0

不同大小的數字類型:

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%A4%A7%E5%B0%8F

性能

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E9%80%89%E6%8B%A9%E6%95%B0%E5%80%BC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B

wraparound:

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E6%BA%A2%E5%87%BA-vs-%E6%8A%98%E5%8F%A0

wraparound:

https://gocn.github.io/How-To-Code-in-Go/docs/07-Understanding_Data_Types_in_Go/#%E6%BA%A2%E5%87%BA-vs-%E6%8A%98%E5%8F%A0

理解 Go 中的數據類型:

docs/07-Understanding_Data_Types_in_Go.md

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/TaIChCmVoeWvB-vaJ2J2xQ