Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

Go语言中快速简便的打印调试

Posted on 2026-01-08

我在新工作中写了很多 Go 代码,并且努力理解一个新的代码库。

当我阅读不熟悉的代码时,我喜欢使用打印调试来追踪代码的运行情况。我会打印出当前所在的循环分支、不同变量的值、正在调用的函数等等。有些人喜欢调试器或类似的工具,但对于学习一门新语言来说,它们是需要学习的另一项内容——而打印“Hello World”却是所有语言教程的第一步。

Go 语言内置的打印调试方法是使用fmt.Printf或log.Printf 。这当然没问题,但是我的调试信息会混杂在现有的日志中,因此很难找到,而且这些调试语句很容易在代码审查中被忽略。

相反,我从Ping Yee 的 Python 模块“q”中汲取了灵感。如果你还不熟悉这个模块,我推荐你观看他的闪电演讲,他在演讲中解释了在海量日志中查找单个变量的挫败感。他的模块提供了一个名为qq()函数,可以将任何表达式记录到一个独立的文件中。这个函数编写起来既快捷又简单,而且输出结果与你其他的日志记录完全分离。

我用 Go 语言也做了类似的东西:一个导出单个函数Q()的模块,并将接收到的所有内容记录到/tmp/q.txt中。以下是一个示例:

 package main import ( "github.com/alexwlchan/q" "os" ) func printShapeInfo ( name string , sides int ) { qQ ( "a %s has %d sides" , name , sides ) } func main () { qQ ( "hello world" ) qQ ( 2 + 2 ) _ , err := os.Stat ( "does_not_exist.txt" ) qQ ( err ) printShapeInfo ( "triangle" , 3 ) }日志输出package main import ( "github.com/alexwlchan/q" "os" ) func printShapeInfo ( name string , sides int ) { qQ ( "a %s has %d sides" , name , sides ) } func main () { qQ ( "hello world" ) qQ ( 2 + 2 ) _ , err := os.Stat ( "does_not_exist.txt" ) qQ ( err ) printShapeInfo ( "triangle" , 3 ) }

/tmp/q.txt包含了函数名以及传递给Q()表达式:

 main : "hello world" main : 2 + 2 = 4 main : err = stat does_not_exist.txt: no such file or directory printShapeInfo : a triangle has 3 sides

我通常打开一个终端窗口运行tail -f /tmp/q.txt来查看q记录的内容。

这个模块只有 120 行 Go 代码,可以在 GitHub 上找到。你可以把它复制到你的项目中,或者它足够简单,你也可以自己编写一个版本。它有两个有趣的想法,或许可以有更广泛的应用。

获取runtime包的上下文

调用Q()时,它会接收最终值——例如,如果调用Q(2 + 2) ,它会接收4但我希望记录原始表达式和函数名。这是 Ping 的 Python 包的一个特性,也是 q 函数如此易用的原因。它为日志消息提供了上下文,省去了您手动输入上下文的麻烦。

我从 Go 的runtime包中获取此信息,特别是runtime.Caller函数,该函数提供有关当前正在运行的函数的信息。

我调用runtime.Caller(1)将调用栈向上移动 1 行,找到我在代码中输入Q().它会告诉我“程序计数器”、文件名和行号。我可以使用runtime.FuncForPC将程序计数器解析为函数名,然后打开文件并查找该行以读取表达式。(这假设源代码自编译以来没有更改,而当我进行本地调试时,这总是成立的。)

不会通过本地 .gitignore 文件影响我的同事

为了使用这个文件,我将q.go复制到我的工作仓库中,并将其添加到.git/info/exclude文件中。后者是一个仅本地生效的忽略文件,与会被提交到仓库的.gitignore文件不同。这意味着我不会意外地将q.go提交到仓库或推送到 GitHub。

这也意味着我不能忘记删除我的调试代码,因为如果我这样做,CI 中的测试将找不到q.go从而导致测试失败。

这样就避免了其他更具破坏性或更令人恼火的方法,例如将其作为项目依赖项或将其添加到共享的.gitignore文件中。

[如果您的RSS阅读器中此文章的格式显示异常,请访问原文]

原文: https://alexwlchan.net/2026/q-but-for-go/?ref=rss

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Alin Panaitiu
  • Anil Dash
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Big Technology
  • Bits about Money
  • Brandon Skerritt
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Dalool
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • HeardThat Blog
  • Henrique Dias
  • Herman Martinus
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Li Haoyi
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Maggie Appleton
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mind Matters
  • Mostly metrics
  • Naval Ravikant
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • PostHog
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Slava Akhmechet
  • Small Good Things
  • Steph Ango
  • Stephen Wolfram
  • Steve Blank
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • Wes Kao
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2026 搞英语 → 看世界 | Design: Newspaperly WordPress Theme