📐 第02课:变量与类型

Go基础 第1阶段·第2/7课

📋 本课目标

🔬 代码演示与验证

package main
import ("fmt";"math";"reflect";"unsafe")
func main() {
    var name string = "Go开发者"; var age int = 25; var score float64 = 98.5; var isPassed bool = true
    fmt.Println("=== 基本类型 ===")
    fmt.Printf("姓名: %s, 类型: %T, 大小: %d字节\n", name, name, unsafe.Sizeof(name))
    fmt.Printf("年龄: %d, 类型: %T, 大小: %d字节\n", age, age, unsafe.Sizeof(age))
    x := 42; pi := math.Pi; greeting := "你好"
    fmt.Println("\n=== 短变量声明 ==="); fmt.Printf("x=%d, pi=%.6f, greeting=%s\n", x, pi, greeting)
    var zi int; var zf float64; var zs string; var zb bool
    fmt.Println("\n=== 零值 ==="); fmt.Printf("int: %d, float: %f, string: %q, bool: %t\n", zi, zf, zs, zb)
    var a int = 100; var b float64 = float64(a)
    fmt.Println("\n=== 类型转换 ==="); fmt.Printf("int→float64: %d → %f\n", a, b)
    const AppName = "GoBackend"; type Season int
    const (Spring Season = iota; Summer; Autumn; Winter)
    fmt.Println("\n=== 常量与iota ==="); fmt.Printf("AppName=%s, 春=%d 夏=%d 秋=%d 冬=%d\n", AppName, Spring, Summer, Autumn, Winter)
    fmt.Println("\n=== 位运算 ==="); fmt.Printf("5&3=%d 5|3=%d 5^3=%d\n", 5&3, 5|3, 5^3)
    s := "Hello, 世界"; fmt.Println("\n=== 字符串 ==="); fmt.Printf("字节: %d, rune: %d\n", len(s), len([]rune(s)))
    val := 42; ptr := &val; fmt.Println("\n=== 指针 ==="); fmt.Printf("值=%d, 解引用=%d\n", val, *ptr)
    fmt.Println("\n=== reflect ==="); fmt.Printf("name类型: %v\n", reflect.TypeOf(name))
    type Permission int; const (Read Permission = 1 << iota; Write; Execute; Admin)
    fmt.Println("\n=== iota位标志 ==="); fmt.Printf("Read=%d Write=%d Execute=%d Admin=%d\n", Read, Write, Execute, Admin)
}

🔍 运行验证

⚠️ 需调整 — 实机运行结果:

ERROR: # command-line-arguments
./main.go:4:60: score declared and not used
./main.go:4:86: isPassed declared and not used

🧠 类型系统

基本: bool/int/float/string/rune/byte 复合: 数组/切片/映射/结构体 引用: 指针/函数/通道/接口

📝 变量声明

var name string = "Go"  // 完整
x := 42                   // 短声明
var (port=8080; debug=false)  // 批量

🔄 类型转换

var a int = 100; var b float64 = float64(a) // 必须显式
s := strconv.Itoa(42)  // int→string
⚠️ 溢出:uint8(300)=44,不报错!

🎯 iota模式

type Permission int
const (Read Permission = 1 << iota; Write; Execute; Admin)

🔗 字符串与指针

s := "Hello, 世界"; len(s)  // 13字节; len([]rune(s))  // 9字符
val := 42; ptr := &val; *ptr = 100

🔑 本课要点回顾

知识点关键内容
变量声明var/:=/批量
基本类型bool/int/float/string/rune
类型转换必须显式转换
常量iota位标志/跳过值
字符串UTF-8不可变
指针&取地址/*解引用

🏋️ 练习

类型侦探

用reflect/unsafe输出类型大小

iota权限

位标志权限系统

字符串统计

UTF-8字节/rune/中英统计

🏆

成就解锁:类型大师!

📖 深入类型系统

类型底层大小

类型大小零值说明
bool1false不能与整数互转
int810-128~127
int1620-32768~32767
int32/rune40Unicode码点
int6480大整数
float3240.0约7位精度
float6480.0约15位精度
string16(header)""UTF-8不可变
slice24(header)nilptr+len+cap
map8(pointer)nil哈希表指针

📐 类型转换实战

// 数值互转 — 必须显式
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

// 字符串与数值 — strconv包
s := strconv.Itoa(42)             // int → "42"
n, err := strconv.Atoi("42")      // "42" → int
f, err := strconv.ParseFloat("3.14", 64)

// 字符串与字节
b := []byte("hello")              // string → []byte
s := string(b)                     // []byte → string

// 字符串与rune
r := []rune("你好")               // string → []rune
s := string(r)                     // []rune → string

🎯 iota的5种妙用

// 1. 递增枚举
const (A = iota; B; C)  // 0,1,2

// 2. 位标志
const (Read = 1<<iota; Write; Execute)  // 1,2,4

// 3. 跳过值
const (_ = iota; KB = 1<<(10*iota); MB; GB)  // _,1024,1<<20,...

// 4. 自定义表达式
const (A = iota*10; B; C)  // 0,10,20

// 5. 按组重置
const (
    A = iota  // 0
    B         // 1
)
const (
    C = iota  // 0 (新const块重置)
    D         // 1
)

🔗 字符串高级操作

// strings包常用
strings.Contains(s, "Go")        // 包含
strings.HasPrefix(s, "Hello")    // 前缀
strings.HasSuffix(s, "世界")     // 后缀
strings.Count(s, "l")            // 计数
strings.Index(s, "Go")           // 索引
strings.Repeat("Go", 3)          // 重复
strings.Replace(s, "old", "new", -1) // 替换
strings.Fields("  hello world  ") // 按空白分割

// strconv常用
strconv.FormatInt(42, 16)         // "2a" (十六进制)
strconv.FormatBool(true)          // "true"
strconv.Quote(`hello "world"`)   // 转义引号

📖 延伸阅读

📖 延伸阅读与资源

🎯 实战开发建议

  1. 动手编码 — 只看不练等于没学,每课代码必须自己敲一遍
  2. 使用go docgo doc fmt.Printf 查看标准库文档
  3. 编写测试go test 验证你的理解是否正确
  4. 阅读源码 — 标准库是Go最佳实践的活教材
  5. 项目实战 — 在真实项目中应用所学

⚡ Go性能优化清单

// 1. 预分配切片容量 — 避免频繁扩容
s := make([]int, 0, expectedSize)

// 2. strings.Builder拼接 — 比fmt.Sprintf快3-5倍
var b strings.Builder
b.WriteString("hello")
b.WriteString(" world")
result := b.String()

// 3. sync.Pool对象复用 — 减少GC压力
var bufPool = sync.Pool{
    New: func() interface{} { return new(bytes.Buffer) },
}
buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf)

// 4. 减少堆分配 — 小对象栈分配,避免逃逸
// 用 go build -gcflags="-m" 分析逃逸

// 5. 使用benchmark验证性能
func BenchmarkXxx(b *testing.B) {
    for i := 0; i < b.N; i++ {
        // 被测代码
    }
}
// go test -bench=. -benchmem

🔍 调试与排查技巧

// 1. 格式化调试输出
fmt.Printf("%+v
", myStruct)  // 带字段名
fmt.Printf("%#v
", myValue)   // Go语法表示

// 2. log包运行时日志
log.Printf("[DEBUG] value=%v", val)
log.SetFlags(log.LstdFlags | log.Lshortfile)

// 3. delve源码调试器
// 安装: go install github.com/go-delve/delve/cmd/dlv@latest
// 使用: dlv debug ./main.go
// 命令: break main.main / continue / next / print

// 4. pprof性能分析
import _ "net/http/pprof"
go http.ListenAndServe(":6060", nil)
// 访问: http://localhost:6060/debug/pprof/
// 命令: go tool pprof http://localhost:6060/debug/pprof/profile

// 5. race detector竞态检测
// go run -race main.go
// go test -race ./...

📊 Go工具生态

工具用途安装
golangci-lint代码静态检查go install github.com/golangci/golangci-lint/cmd/...@latest
gofumpt代码格式化(增强)go install mvdan.cc/gofumpt@latest
goimports自动管理importgo install golang.org/x/tools/cmd/goimports@latest
dlv源码调试器go install github.com/go-delve/delve/cmd/dlv@latest
air热重载开发go install github.com/cosmtrek/air@latest
swagSwagger文档生成go install github.com/swaggo/swag/cmd/swag@latest
migrate数据库迁移go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

🏗️ Go项目结构最佳实践

myproject/
├── cmd/                    # 可执行程序入口
│   └── server/
│       └── main.go
├── internal/               # 私有代码(不可外部导入)
│   ├── handler/            # HTTP处理
│   ├── service/            # 业务逻辑
│   ├── repository/         # 数据访问
│   └── model/              # 数据模型
├── pkg/                    # 可复用公共包
│   └── utils/
├── api/                    # API定义(proto/openapi)
├── configs/                # 配置文件
├── scripts/                # 构建/部署脚本
├── test/                   # 集成测试
├── go.mod
├── go.sum
├── Makefile
└── Dockerfile