第 2 章:基本数据类型与变量

jerry北京市2026年4月24日Go 5 次阅读 约 10 分钟
第 2 章:基本数据类型与变量

掌握 Go 的类型系统、变量声明方式、常量定义以及零值机制。


2.1 变量声明

Go 有多种变量声明方式:

// 方式一:完整声明
var name string = "Go"

// 方式二:类型推断
var age = 25

// 方式三:短变量声明(只能在函数内使用,最常用)
city := "Beijing"

// 方式四:批量声明
var (
    x int
    y string
    z bool
)

短变量声明 := 是日常开发中最常用的方式,但注意它只能在函数体内使用。

2.2 基本数据类型

整数类型

类型 大小 范围
int8 1 字节 -128 ~ 127
int16 2 字节 -32768 ~ 32767
int32 4 字节 -2^31 ~ 2^31-1
int64 8 字节 -2^63 ~ 2^63-1
int 平台相关 32 位或 64 位
uint8 (byte) 1 字节 0 ~ 255
uint16 2 字节 0 ~ 65535
uint32 4 字节 0 ~ 2^32-1
uint64 8 字节 0 ~ 2^64-1
var a int = 42
var b int64 = 9223372036854775807
var c byte = 'A'  // byte 是 uint8 的别名

浮点数

var f1 float32 = 3.14
var f2 float64 = 3.141592653589793  // 默认推断为 float64

布尔类型

var ok bool = true
// Go 中布尔值不能与整数互转,不能用 0/1 代替

字符串

s1 := "Hello"           // 双引号:解释型字符串
s2 := `Hello\nWorld`     // 反引号:原始字符串,不转义

// 字符串是不可变的
// s1[0] = 'h'  // 编译错误

// 字符串拼接
s3 := s1 + " World"

// 常用操作
len(s1)                          // 字节长度:5
fmt.Println([]rune("你好"))       // 转为 rune 切片处理中文

rune 类型

// rune 是 int32 的别名,表示一个 Unicode 码点
var r rune = '中'
fmt.Println(r)  // 输出:20013(Unicode 码点)

// 遍历中文字符串
for i, ch := range "你好Go" {
    fmt.Printf("索引:%d 字符:%c\n", i, ch)
}

2.3 零值(Zero Value)

Go 中所有变量在声明时如果没有显式赋值,会被自动初始化为该类型的零值:

类型 零值
int, float64 等数值类型 0
bool false
string "" (空字符串)
指针、切片、映射、通道、函数、接口 nil
var i int       // 0
var f float64   // 0
var b bool      // false
var s string    // ""
var p *int      // nil

这是 Go 的一个重要设计:不存在"未初始化的变量"。

2.4 常量

const pi = 3.14159
const (
    StatusOK    = 200
    StatusNotFound = 404
)

iota 枚举器

iota 是 Go 的常量计数器,在 const 块中从 0 开始自增:

const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
    Wednesday      // 3
    Thursday       // 4
    Friday         // 5
    Saturday       // 6
)

// 常见技巧:位运算
const (
    Read    = 1 << iota  // 1
    Write                // 2
    Execute              // 4
)

// 跳过某个值
const (
    A = iota  // 0
    _         // 1(跳过)
    C         // 2
)

2.5 类型转换

Go 没有隐式类型转换,所有转换必须显式进行:

var i int = 42
var f float64 = float64(i)    // int -> float64
var u uint = uint(f)          // float64 -> uint

// 字符串与数字互转
import "strconv"

s := strconv.Itoa(42)           // int -> string: "42"
n, err := strconv.Atoi("42")   // string -> int: 42

// 字符串与字节切片互转
bs := []byte("hello")          // string -> []byte
str := string(bs)              // []byte -> string

2.6 类型别名与自定义类型

// 自定义类型(创建新类型)
type Celsius float64
type Fahrenheit float64

var temp Celsius = 36.5
// var f Fahrenheit = temp  // 编译错误:类型不同

// 类型别名(只是别名,本质相同)
type MyInt = int
var x MyInt = 10
var y int = x  // OK,因为 MyInt 就是 int

自定义类型和类型别名的区别是面试常考点:

  • 自定义类型 type A B 创建了一个全新的类型,不能直接赋值
  • 类型别名 type A = B 只是起了个别名,完全等价

2.7 面试要点

  1. :=var 的区别是什么?

    • := 只能在函数内使用,自动推断类型
    • var 可以在函数外使用,可以显式指定类型
  2. Go 的零值机制有什么好处?

    • 避免未初始化变量的 bug
    • 简化代码,很多场景不需要显式初始化
  3. byterune 的区别?

    • byte = uint8,表示一个 ASCII 字符或一个字节
    • rune = int32,表示一个 Unicode 码点
  4. 为什么 Go 没有隐式类型转换?

    • 避免隐式转换带来的精度丢失和意外行为
    • 让代码意图更明确

练习

  1. 声明不同类型的变量,打印它们的零值
  2. 使用 iota 定义一组表示文件权限的常量(读、写、执行)
  3. 编写一个程序,将华氏温度转换为摄氏温度:C = (F - 32) * 5 / 9
  4. 遍历字符串 "Hello, 世界" 并打印每个字符及其索引

← 上一章:Go 语言初识与环境搭建 | 下一章:流程控制与函数 →

评论

登录 后发表评论

暂无评论