dustin/go-humanize · 上手攻略

  • 仓库:dustin/go-humanize
  • 链接:https://github.com/dustin/go-humanize
  • 分类:Go 工具库 / 格式化
  • 作者:Tom
  • 更新:2026-08-27

是什么

go-humanize 是 Go 语言的一个小型标准库补充,专门把机器友好的原始数值(字节数、时间戳、科学计数)转成人类可读的字符串。核心解决的是日志、CLI、存储展示中"82854982 字节"这种丑数字让用户困惑的问题。库体积极小(无外部依赖)、API 稳定,是 Go 社区里事实标准的人化格式工具。

解决什么问题

  • 字节数:82854982"83 MB""79 MiB"(SI/IEC 双模式)
  • 时间:time.Time"7 hours ago"(相对时间)
  • 数字:1234567 → "1,234,567"(千分位逗号)
  • 序数词:193 → "193rd"
  • 浮点:2.240000"2.24"(去尾零)
  • SI 前缀:0.00000000223"2.23 nM"
  • 英文复数:42 objects / 1 object(自动复数)

快速安装

go get github.com/dustin/go-humanize

导入路径为 github.com/dustin/go-humanize,常用别名 humanize

核心用法

字节数(最常用)

import "github.com/dustin/go-humanize"

// SI 进制(1000 倍率)
humanize.Bytes(82854982)       // → "83 MB"

// IEC 进制(二进制,2^10 倍率)
humanize.IBytes(82854982)      // → "79 MiB"

// 大数(超出 uint64 范围)
humanize.BigBytes(big.NewInt(82854982))
humanize.BigIBytes(big.NewInt(82854982))

⚠️ Bytes 使用 SI 十进制(1 KB = 1000 B),IBytes 使用 IEC 二进制(1 KiB = 1024 B),首次使用务必确认用的是哪种进制,否则在日志里会产生 2.4%–7% 的显示误差。

相对时间

import "github.com/dustin/go-humanize"

someTime := time.Date(2026, 8, 27, 10, 0, 0, 0, time.UTC)
humanize.Time(someTime)  // → "7 hours ago"(以当前时间为基准)

⚠️ Time() 以运行时刻为参照,相同代码在不同时刻执行结果不同,不适合做日志序列化(改用 time.Time.Format())。

千分位数字

humanize.Comma(6582491)       // → "6,582,491"
humanize.Commaf(6582491.42)   // → "6,582,491.42"

浮点格式化(去尾零)

humanize.Ftoa(2.24)    // → "2.24"
humanize.Ftoa(2.0)     // → "2"        (不再输出 "2.000000")

序数词

humanize.Ordinal(1)   // → "1st"
humanize.Ordinal(2)   // → "2nd"
humanize.Ordinal(3)   // → "3rd"
humanize.Ordinal(193) // → "193rd"

SI 科学计数

humanize.SI(0.00000000223, "M")  // → "2.23 nM"
humanize.SI(1000, "Hz")          // → "1 kHz"

英文复数(english 子包)

import "github.com/dustin/go-humanize/english"

english.Plural(42, "object", "")    // → "42 objects"
english.Plural(1, "object", "")     // → "1 object"
english.Plural(2, "bus", "")        // → "2 buses"
english.PluralWord(99, "locus", "loci")  // → "loci"

// 列表连接
english.WordSeries([]string{"foo", "bar", "baz"}, "and")
// → "foo, bar and baz"

english.OxfordWordSeries([]string{"foo", "bar", "baz"}, "and")
// → "foo, bar, and baz"

自定义相对时间

humanize.CustomRelTime(a, b, "earlier", "later", magnitudes)
humanize.RelTime(a, b, "earlier", "later")

典型适用场景

场景 示例
CLI 工具输出文件大小 du 类工具显示 "2.4 GiB" 而非 2576980378
日志/监控面板 显示 "请求耗时 3.2s" 而非 "3200ms"
邮件/通知文案 "您的文件 2 天前已上传"
进度条/百分比浮点 "已完成 45%" 而非 "0.450000"
学术/实验数据展示 "第 193rd 次实验"

坑与注意

  1. SI vs IEC 混淆:Go 生态里 strconv.FormatUint 等原生函数用 SI,而 humanize.Bytes 默认也用 SI。若系统用二进制单位(Linux ls -lh 显示 KiB),请改用 IBytes。混用会导致报告的数值看起来"偏小"。

  2. Time() 不适合序列化:相对时间本质上是"快照",相同 time.Time 在不同调用时刻会产生不同字符串,不可用于需要幂等的场景。

  3. 包版本:godoc 显示 v1.0.1 tag,使用 go get 时建议锁定版本: bash go get github.com/dustin/go-humanize@v1.0.1

  4. 导入别名冲突:部分项目习惯性用 h "github.com/dustin/go-humanize",但 hhumanize 混用容易造成 Code Review 歧义,建议直接 humanize

  5. english.PluralWord 需要不规则复数参数:对于不规则名词(bus→buses, locus→loci),第二个参数必须传入复数形式;若传入空字符串则按规则复数处理。

与同类对比

语言 特色 适合场景
dustin/go-humanize Go 无依赖、体积小、SI/IEC 双模式 Go 项目首选
charmbracelet/humanize Go 彩色输出、CLI 美化 需要 TUI 场景
django.utils.formats Python Django 生态 Python Web 项目
numeral.js JavaScript 浏览器端格式化 前端展示

Go 生态里 go-humanize 是几乎唯一选择(另一个是 charmbracelet/humanize,但有彩色 TUI 依赖)。

一句话推荐结论

如果你的 Go 服务需要在日志、CLI、监控面板里展示数字、时间或文件大小,直接 go get github.com/dustin/go-humanize,无需比较——它是 Go 生态里最小、最稳的事实标准。