Go语言整数类型深度解析:从选择到应用全方位讲解

Go语言整数类型深度解析:从选择到应用全方位讲解

在Go语言中,整数类型的选择是影响程序性能和正确性的关键因素之一。Go提供了多种整数类型,包括有符号和无符号整数,每种类型都有不同的取值范围和内存需求。正确地理解和选择整数类型,能够有效避免溢出、内存浪费等问题,提升程序的稳定性和效率。本文将深入探讨Go语言中的整数类型,涵盖其基本概念、常见应用场景,以及如何根据需求选择最合适的类型。通过本篇文章,您将全面掌握Go语言整数类型的使用技巧,从而在实际开发中做出更明智的决策。

Go语言中的整数类型非常多样化,开发者需要根据程序的需求和平台架构,合理选择整数类型。文章首先介绍了Go语言中的基本整数类型,包括有符号和无符号整数,随后分析了每种类型的取值范围、内存占用以及应用场景。特别地,文中对int、uint、int8、uint8等常见类型的特点进行了详细讲解,并通过实例说明了如何使用这些类型来处理不同规模的数据。文章还讨论了整数溢出、环绕现象以及如何避免这些问题,从而保证代码的健壮性和稳定性。最后,我们为开发者提供了整数类型选择的最佳实践建议,帮助读者在实际开发中做出优化决策。

整数类型

Go语言里的整数类型

  • Go提供了10种整数类型:
  • 不可以存小数部分
  • 范围有限
  • 通常根据数值范围来选取整数类型
  • 5种整数类型是有符号的
  • 能表示正数、0、负数
  • 5种整数类型是无符号的
  • 能表示正数、0

例子

  • 最常用的整数类型是int:var year int = 2025
  • 无符号整数类型是uint:var month uint = 2

例子 – 使用类型推断

  • 下面三个语句是等价的:
year := 2025
var year = 2025
var year int = 2025

8种整数类型

  • 整数类型,包括有符号和无符号的,实际上一共是8种类型:
  • 他们的取值范围各不相同。
  • 与架构无关
  • int8 uint8 int16 uint16 int32 uint32 int64 uint64

int和uint

  • 而int和uint是针对目标设备优化的类型:
  • 在树莓派2、比较老的移动设备上,int和uint都是32位的。
  • 在比较新的计算机上,int和uint都是64位的。
  • Tip:
  • 如果你在较老的32位设备上,使用了超过20亿的整数,并且代码还能运行,那么最好使用int64和uint64来代替int和uint

  • 虽然在某些设备上int可以看作是int32,在某些设备上int可以看作是int64,但它们其实是3种不同的类型。

  • int并不是其它类型的别名

小测试

  • 哪些整数类型能够包含 –20251021?

打印数据类型

  • 在Printf里使用%T就可以打印出数据的类型。
package main

import (
 "fmt"
)

// main is the function where it all begins.
func main() {
 year := 2025
 fmt.Printf("Type %T for %v\n", year, year)

 a := "text"
 fmt.Printf("Type %T for %[1]v\n", a)

 b := 42
 fmt.Printf("Type %T for %[1]v\n", b)

 c := 3.14
 fmt.Printf("Type %T for %[1]v\n", c)

 d := true
 fmt.Printf("Type %T for %[1]v\n", d)
}

运行

Code/go/hello via 🐹 v1.20.3 
➜ go run main.go 
Type int for 2025
Type string for text
Type int for 42
Type float64 for 3.14
Type bool for true

Code/go/hello via 🐹 v1.20.3 
➜ 

uint8

  • uint8可以用来表示8位的颜色(红绿蓝:0-255)。
  • var red, green, blue uint8 = 0, 141, 213
  • 为什么不使用int?
  • uint8的取值范围正好合适,而int则多出来几十亿不合理的数。
  • 如果很多颜色数据连续存储,例如未被压缩的图片,那么使用uint8可以节省很多内存。

十六进制表示法

  • Go语言里,在数前面加上0x前缀,就可以用十六进制的形式来表示数值。
var red, green, blue uint8 = 0, 141, 213
var red, green, blue uint8 == 0x00, 0x8d, 0xd5

打印十六进制

  • 打印十六进制的数,使用%x格式化动词
fmt.Printf("%x %x %x", red, green, blue)
  • 也可以指定最小宽度和填充:
var red, green, blue uint8 = 0, 141, 213
fmt.Printf("clolr: #%02x%02x%02x;", red, green, blue)

问题

  • 存储一个uint8的变量需要多大内存?

整数环绕

  • 所有的整数类型都有一个取值范围,超出这个范围,就会发生“环绕”
var red uint8 = 255
red++
fmt.Println(red)  // 0

var number int8 = 127
number++
fmt.Println(number)  // -128

打印每个bit

  • 使用%b格式化动词
var green uint8 = 3
fmt.Printf("%08b\n", green)  // 00000011
green++
fmt.Printf("%08b\n", green)  // 00000100

为什么会发生整数环绕?

整数类型的最大、最小值

  • math包里,为与架构无关的整数类型,定义了最大、最小值常量:
  • math.MaxInt16
  • math.MinInt64
  • 而int和uint,可能是32或64位的。

如何避免时间发生环绕

  • Unix系统里,时间是以1970年1月1日至今的秒数来表示的。
  • 但是在2038年,这个数就会超过20多亿,也就是超过了int32的范围。
  • 应使用:int64或uint64
package main

import (
 "fmt"
 "time"
)

// main is the function where it all begins.
func main() {
 future := time.Unix(12622780800, 0)
 fmt.Println(future)
}

作业题

  • 编写一个新的存钱罐程序,它使用整数来跟踪美分而不是美元的数量。:
  • 随机将五分镍币(5美分)、一角硬币(10美分)和25美分硬币(25美分)放入一个空的储蓄罐,直到里面至少有20美元。
  • 以美元显示每次存款后存钱罐的余额(例如$1.05)。

总结

通过本文的讲解,我们深入了解了Go语言中各类整数类型的特点和应用。无论是在处理常规数据、图像处理,还是在进行高性能计算时,选择合适的整数类型都至关重要。掌握整数类型的选择技巧,不仅有助于提升代码性能,还能避免由于溢出或内存浪费带来的潜在问题。希望读者通过本文能够加深对Go语言整数类型的理解,并在项目开发中得心应手地使用这些类型,以实现更高效、稳定的程序。

全部评论(0)