1 Go语言数据类型简介
在Go语言中,数据类型是编程的基础,它决定了变量可以存储的数据形式。Go语言提供的基础数据类型主要有以下几类:
数据类型 | 描述 | 内存占用 |
---|---|---|
bool | 布尔型,用于存储真假值 | 1字节 |
int, uint | 有符号和无符号整型,默认大小取决于系统平台 | 4或8字节 |
int8, uint8 | 8位有符号和无符号整型 | 1字节 |
int16, uint16 | 16位有符号和无符号整型 | 2字节 |
int32, uint32 | 32位有符号和无符号整型 | 4字节 |
int64, uint64 | 64位有符号和无符号整型 | 8字节 |
float32 | 32位浮点数 | 4字节 |
float64 | 64位浮点数 | 8字节 |
complex64 | 32位实数和虚数部分的复数 | 8字节 |
complex128 | 64位实数和虚数部分的复数 | 16字节 |
byte | 类似 uint8 | 1字节 |
rune | 类似 int32,表示Unicode码点 | 4字节 |
string | 字符串类型 | 取决于字符串长度 |
error | 错误接口,用于返回错误信息 | 无固定大小 |
这些类型可以针对不同的需求进行选择,例如数字计算、文本处理或者逻辑控制。
2 整型数据类型
2.1 整型概述
Go语言内置多种整型,分为以下几类:
- 有符号整型:
int8
、int16
、int32
(rune
)、int64
和int
- 无符号整型:
uint8
(byte
)、uint16
、uint32
、uint64
和uint
int
和uint
的大小在32位系统中为4字节,在64位系统中为8字节。整型数据类型的取值范围如下表所示:
类型 | 取值范围 |
---|---|
int8 | -128 到 127 |
uint8 | 到 255 |
int16 | -32768 到 32767 |
uint16 | 到 65535 |
int32 | -2147483648 到 2147483647 |
uint32 | 到 4294967295 |
int64 | -9223372036854775808 到 9223372036854775807 |
uint64 | 到 18446744073709551615 |
2.2 使用整型变量
声明整型变量的基本语法如下:
var 变量名 数据类型 = 初始值
示例代码:
package main
import "fmt"
func main() {
var a int = 10 // 有符号整型变量
var b uint = 20 // 无符号整型变量
var c int8 = -128 // 最小的int8值
fmt.Println(a, b, c)
}
2.3 整型运算
Go语言支持常见的算术运算符,例如加(+
)、减(-
)、乘(*
)、除(/
)和模(%
)等,还包括位运算符如按位与(&
)、或(|
)、异或(^
)、左移(<<
)和右移(>>
)。
package main
import "fmt"
func main() {
x := 10
y := 3
// 算术运算
fmt.Println(x + y) // 加法
fmt.Println(x - y) // 减法
fmt.Println(x * y) // 乘法
fmt.Println(x / y) // 除法
fmt.Println(x % y) // 取模
// 位运算
fmt.Println(x & y) // 按位与
fmt.Println(x | y) // 按位或
fmt.Println(x ^ y) // 按位异或
fmt.Println(x << 1) // 左移1位
fmt.Println(x >> 1) // 右移1位
}
3 浮点型数据类型
3.1 浮点型概述
Go语言中浮点型分为float32
和float64
,分别对应32位和64位浮点数据。一般情况下,推荐使用float64
因为它提供更大的范围和更准确的精度。
-
float32
的有效bit位约为23个,可以提供大约7位十进制数的精度。 -
float64
的有效bit位约为52个,可以提供大约16位十进制数的精度。
3.2 使用浮点型变量
声明浮点型变量可以直接给出字面量,也可以使用var
关键字:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // 显示指定 float32 类型
f2 := 3.14 // 自动推断为 float64 类型
fmt.Println(f1, f2)
}
3.3 浮点数的运算和问题
浮点数在运算时可能会出现精度丢失的问题。精确到很高精度的运算是一个常见问题,尤其是当两个很接近的数字做减法操作的时候。
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // 输出可能不会是我们预期的.3,因为浮点数计算可能会有精度问题
// 使用格式化输出修复精度问题
fmt.Printf("%.1f\n", f3) // 输出修正为 .3
}
4 布尔型数据类型
4.1 布尔型概述
布尔型(boolean)是最简单的数据类型,仅可以取两个值:true
(真)和false
(假)。它在条件判断和循环控制结构中占据非常重要的位置。
4.2 使用布尔型变量
声明和使用布尔型变量:
package main
import "fmt"
func main() {
var success bool = true
var fail bool = false
fmt.Println("Operation successful:", success)
fmt.Println("Operation failed:", fail)
}
布尔值经常在条件语句中使用:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false
fmt.Println("a < b:", a < b) // true
}
5 字符串数据类型
5.1 字符串概述
字符串是一系列字符的集合,在Go语言中,字符串是不可变的。每个字符串由两部分组成:一个指向底层字节数组的指针和一个长度。字符串可以包含任何数据,包括字节。
5.2 使用字符串变量
声明字符串变量通常使用双引号"
来创建,也可以使用反引号`创建多行字符串:
package main
import "fmt"
func main() {
var s1 string = "hello"
s2 := "world"
s3 := `This is a
multiple line
string`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
字符串一旦创建,其内容就不可更改。下面的操作是非法的,并且会在编译时报错:
s := "hello"
s[] = 'H` // 编译错误:字符串的内容不可变
5.3 字符串操作
字符串在编程中非常常见和重要,Go语言提供了丰富的内置函数来进行字符串处理。以下是一些常用的操作。
5.3.1 字符串拼接
在Go语言中,可以使用加号(+
)操作符来拼接字符串,这是最直接的方法。此外,当涉及到对多个字符串进行频繁拼接时,推荐使用strings.Builder
,因为它在性能上更优。
package main
import (
"fmt"
"strings"
)
func main() {
// 使用 + 拼接字符串
hello := "Hello, "
world := "World!"
result := hello + world
fmt.Println(result) // 输出: Hello, World!
// 使用 strings.Builder 拼接字符串
var sb strings.Builder
sb.WriteString("Hello, ")
sb.WriteString("World!")
fmt.Println(sb.String()) // 输出: Hello, World!
}
5.3.2 字符串分割
字符串的分割可以使用strings.Split
函数,它会根据指定的分隔符将字符串分割成一个切片(slice)。
package main
import (
"fmt"
"strings"
)
func main() {
// 定义一个字符串
sentence := "Go is an open source programming language"
// 使用空格分割字符串
words := strings.Split(sentence, " ")
for _, word := range words {
fmt.Printf("%s\n", word)
}
// 输出:
// Go
// is
// an
// open
// source
// programming
// language
}
5.3.3 索引访问
在Go中,字符串是字节的不可变序列。可以使用索引来访问字符串中的特定字节,但需要注意的是,由于字符串可能包含多字节字符(如UTF-8编码的字符),所以直接索引可能并不会得到预期的单个字符。
package main
import "fmt"
func main() {
s := "Hello, 世界"
for i := ; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// 注意:这将输出字节的十六进制表示,而不是字符
}
如果要按字符遍历字符串,可以使用range
循环。
package main
import "fmt"
func main() {
s := "Hello, 世界"
for index, runeValue := range s {
fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
}
// 输出每个字符的索引、Unicode编码和字符本身
}
5.3.4 长度获取
len
函数可以获得字符串的长度,即底层字节序列的长度。对于UTF-8字符串,如果需要获取字符(rune)的数量,则应使用utf8.RuneCountInString
函数,这样可以正确处理多字节字符。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Hello, 世界"
fmt.Println("Bytes length:", len(s)) // 输出字节长度
fmt.Println("Runes length:", utf8.RuneCountInString(s)) // 输出字符长度
}
通过上面的例子,我们可以看到Go语言为字符串操作提供了丰富的库函数,能够方便的完成各种字符串处理任务。在编码时要注意区分字节和字符的概念,尤其是在处理非ASCII字符集的文本时。