Go 是一门强类型、静态类型的通用编程语言,语法简洁,内置了丰富的数据类型。不同的数据类型适合表示不同的值,也支持不同的操作。本文主要介绍 Go 中的常用数据类型,包括:内置数据类型分类、获取变量的数据类型、定义变量并指定数据类型、类型转换与“构造函数风格”的创建、nil(类似 Python 的 None)和常用数据类型综合示例。

1、Go 内置数据类型

在 Go 中,为了更合理利用内存、提高类型安全,我们会为变量指定具体的类型。常见内置类型可以大致分为:

1)基本数据类型

  • 整型:int, int8, int16, int32, int64

  • 无符号整型:uint, uint8(别名 byte), uint16, uint32, uint64

  • 浮点型:float32, float64

  • 复数型:complex64, complex128

  • 布尔型:bool(值为 true / false

  • 字符串:string

  • 字符(Unicode 码点):rune(本质是 int32

2)聚合类型

  • 数组:[N]T 固定长度

  • 切片:[]T 动态长度,最常用的“数组”类型

  • 结构体:struct { ... } 组合多个字段

3)引用 / 复合类型

  • 映射(字典):map[K]V

  • 指针:*T

  • 函数类型:func(...) ...

  • 接口类型:interface{...}

  • 通道:chan T

4)特殊零值 / nil

  • nil:指针、切片、map、chan、函数、接口等的“空值”
    类似 Python 的 None,表示“没有指向任何东西”。

2、使用 %Treflect 获取变量类型

Go 中可以通过 fmt.Printfreflect.TypeOf 来查看变量的类型。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    x := 5
    fmt.Printf("类型: %T\n", x)              // int
    fmt.Println("类型:", reflect.TypeOf(x)) // int

    fmt.Printf("%T\n", "Hello")
    fmt.Printf("%T\n", 3)
    fmt.Printf("%T\n", 3.14)
    fmt.Printf("%T\n", 1+2i)
    fmt.Printf("%T\n", []string{"c", "java", "python"})
    fmt.Printf("%T\n", [3]string{"c", "java", "python"}) // 数组
    fmt.Printf("%T\n", map[string]int{"age": 12})
    fmt.Printf("%T\n", true)
    fmt.Printf("%T\n", byte(5))
}

3、定义变量并指定数据类型

在 Go 中,给变量赋值时,就确定了它的类型(但不能随意改成其他类型)。可以显式写类型,也可以让编译器推断。

package main

import "fmt"

func main() {
    var s string = "Hello World"          // string
    var i int = 20                        // int
    var f float64 = 20.5                  // float64
    var c complex128 = 1 + 2i             // complex128
    nums := []string{"c", "python", "java"} // 切片 slice
    tupleLike := [3]string{"c", "python", "java"} // 数组 array
    r := []int{0, 1, 2, 3, 4, 5}          // 当作“range”生成的切片
    m := map[string]int{"age": 20}        // map
    setLike := map[string]struct{}{       // 集合一般用 map 实现
        "c":      {},
        "python": {},
        "java":   {},
    }
    fs := map[string]bool{"c": true, "python": true} // 另一种简单集合

    b := true  // bool
    by := []byte("Hello") // []byte,相当于 Python 的 bytes

    fmt.Println(s, i, f, c, nums, tupleLike, r, m, setLike, fs, b, by)
}

注意:

Go 没有 list/tuple/dict/set 这些名字,但切片 []T + map[K]V 能覆盖大部分场景。

Go 变量一旦确定类型,就不能随便换成其他类型(需要转换或新建变量)。

4、通过“构造函数式”写法指定类型(类型转换/创建)

Python 用 int(), float(), list() 等构造函数。
Go 中对应的是 类型转换内建函数

常见写法:

package main

import "fmt"

func main() {
    // 基本类型转换
    var s string = "Hello World"          // string
    var i int = int(20)                   // int
    var f float64 = float64(20.5)         // float64
    var c complex128 = complex(0, 1)      // complex128 (0+1i)

    // 切片 & 数组
    arr := [3]string{"c", "python", "java"}  // 数组
    sl := []string{"c", "python", "java"}    // 切片

    // map(类似 dict)
    m := map[string]interface{}{
        "name": "cjavapy",
        "age":  3,
    }

    // “set” 一般用 map 实现
    set := map[string]struct{}{"c": {}, "java": {}, "python": {}}

    // bool 转换(非 0 即 true)
    b := bool(5 != 0) // 手动写逻辑,而不是 bool(5) 这种 Python 写法

    // bytes:常用 []byte
    bytes := make([]byte, 5) // 长度为 5 的字节切片,默认全 0

    fmt.Println(s, i, f, c, arr, sl, m, set, b, bytes)
}

Go 中没有像 bool(5) 这样的隐式转换,必须自己写逻辑决定 true/false

5、nil:Go 里的“空值”

在 Python 中有 NoneType / None
在 Go 中,则是 nil——适用于指针、切片、map、chan、函数、接口等类型。

1)nil 示例

package main

import "fmt"

func main() {
    var p *int      // 指针,默认是 nil
    var s []int     // 切片 nil
    var m map[string]int // map nil
    var ch chan int // 通道 nil

    fmt.Println(p == nil)  // true
    fmt.Println(s == nil)  // true
    fmt.Println(m == nil)  // true
    fmt.Println(ch == nil) // true

    // 使用前记得初始化
    s = make([]int, 0)
    m = make(map[string]int)
    ch = make(chan int)

    fmt.Println(s == nil) // false
    fmt.Println(m == nil) // false
}

2)函数返回值“空”场景

类似 Python 返回 None 的场景,在 Go 中常用 零值或 nil 表示,

package main

import "fmt"

func exampleFunction() error {
    fmt.Println("这是一个示例函数")
    return nil // 没有错误
}

func main() {
    err := exampleFunction()
    if err == nil {
        fmt.Println("result is nil (无错误)")
    }
}

6、Go 常用数据类型综合示例

package main

import (
    "fmt"
    "sort"
)

func main() {
    // 1) 切片:购物清单
    shoplist := []string{"apple", "mango", "carrot", "banana"}

    fmt.Println("我有", len(shoplist), "样物品要购买。")
    fmt.Print("这些物品是:")
    for _, item := range shoplist {
        fmt.Print(item, " ")
    }
    fmt.Println()

    fmt.Println("我还需要买米。")
    shoplist = append(shoplist, "rice")
    fmt.Println("我的购物清单现在是", shoplist)

    fmt.Println("我现在要对购物清单进行排序")
    sort.Strings(shoplist)
    fmt.Println("排序后的购物清单是", shoplist)

    fmt.Println("我将购买的第一样物品是", shoplist[0])
    olditem := shoplist[0]
    shoplist = shoplist[1:] // 删除第 0 项
    fmt.Println("我买了", olditem)
    fmt.Println("我的购物清单现在是", shoplist)

    // 2) 数组 & 嵌套:动物园
    zoo := [3]string{"python", "elephant", "penguin"}
    fmt.Println("动物园里有", len(zoo), "种动物")

    newZoo := [][]string{
        {"monkey"},
        {"camel"},
        zoo[:], // 把数组转成切片挂进来
    }
    fmt.Println("新动物园里有", len(newZoo), "个笼子")
    fmt.Println("新动物园里的所有动物有", newZoo)
    fmt.Println("从旧动物园带来的动物有", newZoo[2])
    fmt.Println("从旧动物园带来的最后一只动物是", newZoo[2][2])

    total := len(newZoo) - 1 + len(newZoo[2])
    fmt.Println("新动物园里的动物总数是", total)

    // 3) map:通讯录
    ab := map[string]string{
        "Swaroop":   "Swaroop@Swaroopch.com",
        "Larry":     "larry@wall.org",
        "Matsumoto": "matz@ruby-lang.org",
        "Spammer":   "spammer@hotmail.com",
    }

    fmt.Println("Swaroop 的地址是", ab["Swaroop"])

    delete(ab, "Spammer")

    fmt.Printf("\n通讯录中有 %d 个联系人\n\n", len(ab))
    for name, address := range ab {
        fmt.Printf("联系 %s 的地址是 %s\n", name, address)
    }

    ab["Guido"] = "guido@python.org"

    if addr, ok := ab["Guido"]; ok {
        fmt.Println("\nGuido 的地址是", addr)
    }

    // 4) 切片 & 字符串索引 / 切片
    name := "Swaroop"

    fmt.Println("第0项是", shoplist[0])
    fmt.Println("第1项是", shoplist[1])
    fmt.Println("第2项是", shoplist[2])
    fmt.Println("倒数第1项是", shoplist[len(shoplist)-1])
    fmt.Println("倒数第2项是", shoplist[len(shoplist)-2])

    fmt.Println("第0个字符是", string(name[0])) // 注意:name[i] 是 byte,需要转 string

    fmt.Println("第1到3项是", shoplist[1:3])
    fmt.Println("第2项到最后是", shoplist[2:])
    fmt.Println("第1项到倒数第1项是", shoplist[1:len(shoplist)-1])
    fmt.Println("从头到尾所有项是", shoplist[:])

    fmt.Println("第1到3个字符是", name[1:3])         // 字符串切片按字节
    fmt.Println("第2个字符到最后是", name[2:])
    fmt.Println("第1个字符到倒数第1个字符是", name[1:len(name)-1])
    fmt.Println("从头到尾所有字符是", name[:])

    // 5) set:用 map 实现
    bri := map[string]struct{}{
        "brazil": {},
        "russia": {},
        "India":  {},
        "China":  {},
    }
    _, exists := bri["India"]
    fmt.Println("India 在 bri 中吗?", exists)
}

  • Go 字符串是 UTF-8 编码,s[i] 取的是 字节,中文会占多个字节,做“按字符”切片时要用 []rune

  • 推荐文档