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 的数据类型特点:

  1. 基本类型:整数、浮点数、布尔、字符串、复数
  2. 复合类型:数组、切片、映射、结构体
  3. 零值概念:每个类型都有默认零值
  4. 类型安全:需要显式类型转换
  5. 切片和映射:动态数据结构,使用方便

掌握这些数据类型后,就可以处理各种数据了!


go 数据类型 变量 数组 切片 映射 结构体