Go 数据类型与变量
基本数据类型
整数类型
package main
import "fmt"
func main() {
// 有符号整数
var i8 int8 = 127
var i16 int16 = 32767
var i32 int32 = 2147483647
var i64 int64 = 9223372036854775807
var i int = 42 // int 是 32 或 64 位,取决于平台
// 无符号整数
var u8 uint8 = 255
var u16 uint16 = 65535
var u32 uint32 = 4294967295
var u64 uint64 = 18446744073709551615
var u uint = 42
// 特殊类型
var b byte = 255 // byte 是 uint8 的别名
var r rune = '中' // rune 是 int32 的别名,用于 Unicode
fmt.Printf("int8: %d, int: %d\n", i8, i)
fmt.Printf("uint8: %d, uint: %d\n", u8, u)
fmt.Printf("byte: %d, rune: %c\n", b, r)
}浮点数类型
package main
import "fmt"
func main() {
// float32:32 位浮点数,精度约 7 位小数
var f32 float32 = 3.141592653589793
fmt.Printf("float32: %.7f\n", f32) // 输出:3.1415927(精度损失)
// float64:64 位浮点数,精度约 15 位小数
var f64 float64 = 3.141592653589793
fmt.Printf("float64: %.15f\n", f64) // 输出:3.141592653589793
// 科学计数法
var num1 = 1.23e4 // 12300
var num2 = 1.23e-4 // 0.000123
fmt.Printf("科学计数法: %g, %g\n", num1, num2)
}布尔类型
package main
import "fmt"
func main() {
var isTrue bool = true
var isFalse bool = false
var zero bool // 零值是 false
fmt.Printf("true: %t, false: %t, zero: %t\n", isTrue, isFalse, zero)
// 布尔运算
result := isTrue && isFalse // false
result2 := isTrue || isFalse // true
result3 := !isTrue // false
fmt.Printf("&&: %t, ||: %t, !: %t\n", result, result2, result3)
}字符串类型
package main
import (
"fmt"
"strings"
)
func main() {
// 字符串是不可变的字节序列
var str1 string = "Hello"
var str2 = "World"
// 字符串连接
combined := str1 + " " + str2
fmt.Println(combined) // "Hello World"
// 字符串长度(字节数,不是字符数)
length := len("Hello") // 5
chineseLength := len("你好") // 6(每个中文字符 3 字节)
fmt.Printf("长度: %d, 中文长度: %d\n", length, chineseLength)
// 字符串索引(返回字节)
firstByte := "Hello"[0] // 72 (H 的 ASCII 码)
fmt.Printf("第一个字节: %d (%c)\n", firstByte, firstByte)
// 字符串切片
substr := "Hello"[1:3] // "el"
fmt.Println(substr)
// 字符串遍历
str := "Hello"
for i := 0; i < len(str); i++ {
fmt.Printf("%c ", str[i]) // H e l l o
}
fmt.Println()
// 遍历 Unicode 字符(推荐)
for _, char := range str {
fmt.Printf("%c ", char) // H e l l o
}
fmt.Println()
// 中文字符串遍历
chinese := "你好"
for _, char := range chinese {
fmt.Printf("%c ", char) // 你 好
}
fmt.Println()
// 字符串常用操作
fmt.Println(strings.Contains("Hello", "ll")) // true
fmt.Println(strings.HasPrefix("Hello", "He")) // true
fmt.Println(strings.HasSuffix("Hello", "lo")) // true
fmt.Println(strings.Index("Hello", "l")) // 2
fmt.Println(strings.Count("Hello", "l")) // 2
fmt.Println(strings.Replace("Hello", "l", "L", 1)) // "HeLlo"
fmt.Println(strings.ToUpper("hello")) // "HELLO"
fmt.Println(strings.ToLower("HELLO")) // "hello"
fmt.Println(strings.TrimSpace(" hello ")) // "hello"
fmt.Println(strings.Split("a,b,c", ",")) // ["a", "b", "c"]
}复数类型
package main
import "fmt"
func main() {
// 复数类型
var c64 complex64 = 1 + 2i
var c128 complex128 = 3 + 4i
// 创建复数
c1 := complex(1, 2) // 1 + 2i
c2 := complex(3, 4) // 3 + 4i
// 获取实部和虚部
realPart := real(c1) // 1
imagPart := imag(c1) // 2
fmt.Printf("复数: %v, 实部: %g, 虚部: %g\n", c1, realPart, imagPart)
// 复数运算
sum := c1 + c2 // (1+2i) + (3+4i) = 4+6i
product := c1 * c2 // (1+2i) * (3+4i) = -5+10i
fmt.Printf("和: %v, 积: %v\n", sum, product)
}复合数据类型
数组
package main
import "fmt"
func main() {
// 数组声明
var arr1 [5]int // [0 0 0 0 0]
var arr2 = [5]int{1, 2, 3, 4, 5} // [1 2 3 4 5]
var arr3 = [...]int{1, 2, 3} // 长度自动推断为 3
// 数组访问
arr1[0] = 10
fmt.Println(arr1[0]) // 10
// 数组长度
fmt.Println(len(arr1)) // 5
// 数组遍历
for i := 0; i < len(arr2); i++ {
fmt.Printf("%d ", arr2[i])
}
fmt.Println()
// 使用 range 遍历
for index, value := range arr2 {
fmt.Printf("索引 %d: 值 %d\n", index, value)
}
// 多维数组
var matrix [3][3]int
matrix[0][0] = 1
matrix[1][1] = 2
matrix[2][2] = 3
fmt.Println(matrix)
}切片(Slice)
package main
import "fmt"
func main() {
// 切片声明(切片是动态数组)
var slice1 []int // nil 切片
var slice2 = []int{1, 2, 3, 4, 5} // 字面量创建
var slice3 = make([]int, 5) // 长度为 5,容量为 5
var slice4 = make([]int, 5, 10) // 长度为 5,容量为 10
// 从数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
slice5 := arr[1:3] // [2 3],包含索引 1,不包含索引 3
slice6 := arr[:3] // [1 2 3],从开始到索引 3
slice7 := arr[2:] // [3 4 5],从索引 2 到结束
slice8 := arr[:] // [1 2 3 4 5],整个数组
// 切片操作
fmt.Println(len(slice2)) // 5,长度
fmt.Println(cap(slice2)) // 5,容量
// 添加元素
slice2 = append(slice2, 6) // 添加一个元素
slice2 = append(slice2, 7, 8, 9) // 添加多个元素
fmt.Println(slice2) // [1 2 3 4 5 6 7 8 9]
// 切片复制
src := []int{1, 2, 3, 4, 5}
dst := make([]int, len(src))
copy(dst, src)
fmt.Println(dst) // [1 2 3 4 5]
// 切片删除(通过重新切片)
slice := []int{1, 2, 3, 4, 5}
index := 2 // 删除索引 2 的元素
slice = append(slice[:index], slice[index+1:]...)
fmt.Println(slice) // [1 2 4 5]
// 切片遍历
for index, value := range slice2 {
fmt.Printf("索引 %d: 值 %d\n", index, value)
}
}映射(Map)
package main
import "fmt"
func main() {
// Map 声明
var map1 map[string]int // nil map
var map2 = make(map[string]int) // 空 map
var map3 = map[string]int{ // 字面量创建
"apple": 5,
"banana": 3,
"orange": 2,
}
// Map 操作
map2["apple"] = 5
map2["banana"] = 3
// 获取值
value := map2["apple"] // 5
fmt.Println(value)
// 检查键是否存在
value, exists := map2["apple"]
if exists {
fmt.Printf("apple 存在,值为 %d\n", value)
}
// 删除键
delete(map2, "apple")
// Map 遍历
for key, value := range map3 {
fmt.Printf("键: %s, 值: %d\n", key, value)
}
// Map 长度
fmt.Println(len(map3)) // 3
}结构体(Struct)
package main
import "fmt"
// 定义结构体
type Person struct {
Name string
Age int
City string
}
func main() {
// 创建结构体实例
var p1 Person
p1.Name = "Alice"
p1.Age = 30
p1.City = "Beijing"
// 字面量创建
p2 := Person{
Name: "Bob",
Age: 25,
City: "Shanghai",
}
// 按顺序创建(不推荐)
p3 := Person{"Charlie", 35, "Guangzhou"}
fmt.Printf("p1: %+v\n", p1) // %+v 显示字段名
fmt.Printf("p2: %+v\n", p2)
fmt.Printf("p3: %+v\n", p3)
// 匿名结构体
p4 := struct {
Name string
Age int
}{
Name: "David",
Age: 28,
}
fmt.Printf("p4: %+v\n", p4)
}类型别名和自定义类型
package main
import "fmt"
// 类型别名(完全相同的类型)
type MyInt = int
// 自定义类型(新类型,需要类型转换)
type UserID int
type Score float64
func main() {
var i int = 42
var mi MyInt = i // 可以直接赋值(类型别名)
var uid UserID = 100
// var i2 int = uid // 错误:需要类型转换
var i2 int = int(uid) // 正确
fmt.Printf("MyInt: %d, UserID: %d\n", mi, i2)
}零值
package main
import "fmt"
func main() {
// 每种类型都有零值
var i int // 0
var f float64 // 0.0
var b bool // false
var s string // ""
var p *int // nil
var sl []int // nil
var m map[string]int // nil
var ch chan int // nil
var iface interface{} // nil
fmt.Printf("int: %d\n", i)
fmt.Printf("float64: %g\n", f)
fmt.Printf("bool: %t\n", b)
fmt.Printf("string: '%s'\n", s)
fmt.Printf("pointer: %v\n", p)
fmt.Printf("slice: %v\n", sl)
fmt.Printf("map: %v\n", m)
fmt.Printf("channel: %v\n", ch)
fmt.Printf("interface: %v\n", iface)
}类型转换
package main
import (
"fmt"
"strconv"
)
func main() {
// 数字类型转换
var i int = 42
var f float64 = float64(i) // int 转 float64
var u uint = uint(f) // float64 转 uint
fmt.Printf("int: %d, float64: %g, uint: %d\n", i, f, u)
// 字符串和数字转换
// 数字转字符串
str1 := strconv.Itoa(123) // "123"
str2 := strconv.FormatInt(123, 10) // "123"(10 进制)
str3 := strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"
// 字符串转数字
num1, err1 := strconv.Atoi("123") // 123, nil
num2, err2 := strconv.ParseInt("123", 10, 64) // 123, nil
num3, err3 := strconv.ParseFloat("3.14", 64) // 3.14, nil
if err1 == nil {
fmt.Printf("字符串转整数: %d\n", num1)
}
if err2 == nil {
fmt.Printf("字符串转整数: %d\n", num2)
}
if err3 == nil {
fmt.Printf("字符串转浮点数: %g\n", num3)
}
// 字符串和字节切片
str := "Hello"
bytes := []byte(str) // []byte{'H', 'e', 'l', 'l', 'o'}
str2 := string(bytes) // "Hello"
fmt.Printf("字符串: %s, 字节: %v, 转回字符串: %s\n", str, bytes, str2)
// 字符串和 rune 切片
str3 := "你好"
runes := []rune(str3) // []rune{'你', '好'}
str4 := string(runes) // "你好"
fmt.Printf("字符串: %s, rune: %v, 转回字符串: %s\n", str3, runes, str4)
}总结
Go 的数据类型特点:
- 基本类型:整数、浮点数、布尔、字符串、复数
- 复合类型:数组、切片、映射、结构体
- 零值概念:每个类型都有默认零值
- 类型安全:需要显式类型转换
- 切片和映射:动态数据结构,使用方便
掌握这些数据类型后,就可以处理各种数据了!