如何在Go中转换数据类型

在Go中,数据类型用于对一种特定类型的数据进行分类,确定可以分配给类型的值以及可以对其执行的操作。编程时,有时您需要在类型之间转换值,以便以不同的方式操作值。本教程将指导您转换数字和字符串,并提供示例以帮助您熟悉不同的用例。

介绍

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

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

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

转换数字类型

Go有几种数字类型可供选择。 它们主要分为两种常规类型: 整数浮点数

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

在整数类型之间转换

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

假设你有一个int8 ,你需要将它转换为int32 您可以通过将其包装在int32()类型转换中来完成此操作:

var index int8 = 15

var bigIndex int32

bigIndex = int32(index)

fmt.Println(bigIndex)
15

此代码块将index定义为int8数据类型,将bigIndex定义为int32数据类型。 要在bigIndex存储index的值,它会将数据类型转换为int32 这是通过在index变量周围包装int32()转换来完成的。

要验证数据类型,可以使用fmt.Printf语句和%T动词,语法如下:

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

由于这使用%T动词,因此print语句输出变量的类型,而不是变量的实际值。 这样,您可以确认转换后的数据类型。

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

var big int64 = 64

var little int8

little = int8(big)

fmt.Println(little)
64

请记住,转换整数时,您可能会超出数据类型的最大值并环绕

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

当值转换为太小而无法容纳它的数据类型时,会发生回绕。 在前面的示例中,8位数据类型int8没有足够的空间来容纳64位变量big 从较大数字数据类型转换为较小数字数据类型时,应始终小心,以免意外截断数据。

将整数转换为浮点数

在Go中将整数转换为浮点类似于将一个整数类型转换为另一个整数类型。 您可以通过在要转换的整数周围包装float64()float32()来使用内置类型转换:

var x int64 = 57

var y float64 = float64(x)

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

此代码声明了类型为int64的变量x ,并将其值初始化为57

var x int64 = 57

x周围包装float64()转换会将57的值转换为浮点值57.00

var y float64 = float64(x)

%.2f打印动词告诉fmt.Printf格式化带有两位小数的浮点数。

您还可以对变量使用此过程。 以下代码将f声明为等于57 ,然后打印出新的float:

var f float64 = 57
fmt.Printf("%.2f\n", f)
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)
f = 390.80
i = 390

此语法将float 390.8转换为整数390 ,删除小数位。

您也可以将此与变量一起使用。 以下代码将b声明为等于125.0c等于390.8 ,然后将它们作为整数打印出来。 短变量声明( := )缩短了语法:

b := 125.0
c := 390.8

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

当使用int()类型将浮点数转换为整数时,Go会截断小数和浮点数的剩余数字以创建整数。 请注意,即使您可能想要将390.8舍入到391,Go也不会通过int()类型执行此操作。 相反,它会丢弃小数。

通过分部转换的数字

在Go中划分整数类型时,结果也将是整数类型,其中模数或余数被删除:

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

如果在划分时,任何数字类型都是浮点数,那么所有类型都将自动声明为浮点数:

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

这将float 5.0除以整数2 ,而答案2.5是一个保留小数精度的float。

在本节中,您已在不同数字数据类型之间进行转换,包括不同大小的整数和浮点数。 接下来,您将学习如何在数字和字符串之间进行转换。

用字符串转换

字符串是一个或多个字符(字母,数字或符号)的序列。 字符串是计算机程序中常见的数据形式,您可能需要经常将字符串转换为数字或数字到字符串,尤其是当您接收用户生成的数据时。

将数字转换为字符串

您可以使用Go标准库中的strconv包中的strconv.Itoa方法将数字转换为字符串。 如果将数字或变量传递到方法的括号中,则该数值将转换为字符串值。

首先,让我们看看转换整数。 要将整数12转换为字符串值,可以将12传递给strconv.Itoa方法:

package main

import (
    "fmt"
    "strconv"
)

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

运行此程序时,您将收到以下输出:

"12"

数字12周围的引号表示该数字不再是整数,而是现在的字符串值。

您使用:=赋值运算符来声明一个名为a的新变量,并分配从strconv.Itoa()函数返回的值。 在这种情况下,您将值12赋给变量。 您还在fmt.Printf函数中使用了%q verb,它告诉函数引用提供的字符串。

使用变量,您可以开始了解将整数转换为字符串的实用性。 假设您希望跟踪用户的日常编程进度,并输入他们一次编写的代码行数。 您希望向用户显示此反馈,并将同时打印出字符串和整数值:

package main

import (
    "fmt"
)

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

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

运行此代码时,您将收到以下错误:

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.")
}

现在,当您运行代码时,您将收到以下输出,以祝贺您的用户进度:

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

如果您希望将float转换为字符串而不是将整数转换为字符串,则遵循类似的步骤和格式。 将float传递给fmt.Sprint方法时,从Go标准库中的fmt包中,将返回float的字符串值。 您可以使用浮点值本身或变量:

package main

import (
    "fmt"
)

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

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

您可以通过连接字符串进行测试以确保它是正确的:

package main

import (
    "fmt"
)

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

您可以确定您的float已正确转换为字符串,因为连接执行时没有错误。

将字符串转换为数字

可以使用Go标准库中的strconv包将字符串转换为数字。 strconv包具有转换整数和浮点数类型的函数。 当接受来自用户的输入时,这是非常常见的操作。 例如,如果您有一个程序要求一个人的年龄,当他们输入响应时,它将被捕获为一个string 然后,您需要将其转换为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)
}
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记录错误并退出程序。

当您运行上述代码时,您将获得:

58

现在尝试转换不是数字的字符串:

package main

import (
    "fmt"
    "strconv"
)

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

您将收到以下错误:

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 然后,您将abc打印到屏幕:

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

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

结论

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

如果您想在Go中更深入地分析数据类型,请查看我们在Go中了解数据类型一文。