跳转到主要内容

介绍


在 Go 中,数据类型用于对一种特定类型的数据进行分类,确定可以分配给该类型的值以及可以对其执行的操作。在编程时,有时您需要在类型之间转换值以便以不同的方式操作值。例如,您可能需要将数值与字符串连接起来,或者在初始化为整数值的数字中表示小数位。用户生成的数据通常会自动分配为字符串数据类型,即使它由数字组成;为了在此输入中执行数学运算,您必须将字符串转换为数字数据类型。

由于 Go 是一种静态类型语言,因此数据类型绑定到变量而不是值。这意味着,如果将变量定义为 int,则它只能是 int;如果不转换变量的数据类型,就无法为其分配字符串。 Go 中数据类型的静态特性使得学习转换它们的方法更加重要。

本教程将指导您完成数字和字符串的转换,并提供示例以帮助您熟悉不同的用例。

转换数字类型


Go 有多种数字类型可供选择。它们主要分为两种一般类型:整数和浮点数。

在许多情况下,您可能希望在数字类型之间进行转换。在不同大小的数字类型之间进行转换有助于优化特定类型系统架构的性能。如果您有来自代码另一部分的整数并想要对其进行除法,您可能需要将整数转换为浮点数以保持操作的精度。此外,使用持续时间通常涉及整数转换。为了解决这些情况,Go 为大多数数字类型提供了内置的类型转换。

整数类型之间的转换


Go 有许多整数数据类型可供选择。何时使用其中一个通常更多的是关于性能;但是,有时您需要从一种整数类型转换为另一种整数类型。例如,Go 有时会自动将数值生成为 int,这可能与您的输入值不匹配。如果您的输入值是 int64,您将无法在同一数学表达式中使用 int 和 int64 数字,除非您将它们的数据类型转换为匹配。

假设您有一个 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() 转换包装在索引变量周围来完成的。

要验证您的数据类型,您可以使用 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 动词,因此 print 语句输出变量的类型,而不是变量的实际值。这样,您可以确认转换后的数据类型。

您还可以从较大的位大小整数转换为较小的位大小整数:

var big int64 = 64

var little int8

little = int8(big)

fmt.Println(little)

 



Output

64


请记住,在转换整数时,您可能会超过数据类型和环绕的最大值:

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


将 float64() 转换包裹在 x 周围会将 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.0 和 c 等于 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 不为零,则表示 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。然后将 a、b 和 c 打印到屏幕上:

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


输出的第一行是原始字符串 my string。打印出来的第二行是组成原始字符串的字节片。第三行显示字节切片可以安全地转换回字符串并打印出来。

结论


本 Go 教程演示了如何主要通过内置方法将几种重要的本机数据类型转换为其他数据类型。能够在 Go 中转换数据类型将允许您执行诸如接受用户输入和跨不同数字类型进行数学运算之类的事情。稍后,当您使用 Go 编写接受来自许多不同来源(如数据库和 API)的数据的程序时,您将使用这些转换方法来确保您可以对数据进行操作。您还可以通过将数据转换为更小的数据类型来优化存储。

文章链接