惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
Project Zero
Project Zero
K
Kaspersky official blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Recorded Future
Recorded Future
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
Microsoft Security Blog
Microsoft Security Blog
H
Help Net Security
S
Schneier on Security
P
Palo Alto Networks Blog
H
Hacker News: Front Page
N
News and Events Feed by Topic
N
Netflix TechBlog - Medium
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Hacker News
The Hacker News
C
Check Point Blog
L
LangChain Blog
腾讯CDC
小众软件
小众软件
T
Tenable Blog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
L
LINUX DO - 最新话题
A
About on SuperTechFans
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
雷峰网
雷峰网
美团技术团队
D
DataBreaches.Net
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
博客园_首页

卡卡罗特

最后代码 | 卡卡罗特 swagger文档 | 卡卡罗特 react脚手架开发 | 卡卡罗特 python的对象增强 | 卡卡罗特 langchain实现Agent | 卡卡罗特 03.python列表集合元组字典 | 卡卡罗特 python依赖打包 | 卡卡罗特 python的异步 | 卡卡罗特 python的生成器 | 卡卡罗特 eino整合Tools | 卡卡罗特 eino实现Agent | 卡卡罗特 eino整合RAG | 卡卡罗特 docker打包go服务 | 卡卡罗特 01-docker入门 | 卡卡罗特 docker-compose | 卡卡罗特 dockerfile | 卡卡罗特 linux安装docker | 卡卡罗特 hertz中间件 | 卡卡罗特 go整合向量数据库ChromaDB | 卡卡罗特 langchainjs | 卡卡罗特 ollama调用各大模型 | 卡卡罗特 spring-ai | 卡卡罗特 自定义一个MCP | 卡卡罗特 context.Context是什么? | 卡卡罗特 01-获取指定网站的所有的链接 | 卡卡罗特 01-Bing每日一图接口 | 卡卡罗特 02-腾讯API高清QQ头像https调用接口 | 卡卡罗特 openCV初体验 | 卡卡罗特 RWMutex读写锁 | 卡卡罗特 SyncMap的使用 | 卡卡罗特
defer的使用 | 卡卡罗特
2026-04-26 · via 卡卡罗特

鼓励作者:欢迎打赏犒劳


✅ 1. defer 是函数级别的

  • defer 绑定在当前函数的作用域中。
  • 当前函数执行完毕(无论是正常返回、return、还是 panic),所有在该函数中注册的 defer 语句都会被执行。
  • 即使函数中有多个 return 分支,defer 也一定会执行(除非程序提前退出,如 os.Exit())。

结论:只要函数开始执行,并且执行到了 defer 语句(注意:defer 是运行时注册的,不是编译时),那么当函数退出时,defer 就会执行。

⚠️ 注意:如果函数因为 panic 而崩溃,defer 依然会执行(这是实现 recover 的基础)。


✅ 2. 多个 defer 的执行顺序:后进先出(LIFO)

Go 中的 defer 遵循 “栈” 的原则:最后注册的 defer 最先执行

示例:

go

package main

import "fmt"

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("main running")
}

输出:

main running
3
2
1

执行顺序:defer 按代码顺序注册 → 执行时逆序调用。


✅ 3. defer 的参数在注册时求值

这是一个常见陷阱!

go

func main() {
    i := 0
    defer fmt.Println("i =", i) // 这里 i 的值是 0(立即求值)
    i = 100
    fmt.Println("end")
}

输出:

end
i = 0

如果你希望使用“函数结束时”的变量值,需要用匿名函数捕获:

go

defer func() {
    fmt.Println("i =", i) // 此时 i 是 100
}()

✅ 4. 特殊情况:os.Exit() 会跳过 defer

go

func main() {
    defer fmt.Println("不会打印!")
    os.Exit(1)
}

defer 不会执行,因为 os.Exit() 直接终止进程。


总结

问题答案
defer 是函数级别的吗?✅ 是,绑定到当前函数
函数执行完就执行 defer 吗?✅ 是(包括 panic,但不包括 os.Exit()
多个 defer 执行顺序?🔁 后注册的先执行(LIFO 栈顺序)
defer 参数何时求值?🕒 注册时立即求值(除非用闭包)