ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenCloud 项目中的 go-humanize:Go 语言人性化数字、字节大小与相对时间格式化实战指南

OpenCloud 项目中的 go-humanize:Go 语言人性化数字、字节大小与相对时间格式化实战指南 OpenCloud 项目中的 go-humanizeGo 语言人性化数字、字节大小与相对时间格式化实战指南【免费下载链接】opencloud️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign.项目地址: https://gitcode.com/GitHub_Trending/op/opencloudgithub.com/dustin/go-humanize是一个轻量级的 Go 工具库提供一组把机器友好的数值变成人类友好字符串的函数字节大小83 MB/79 MiB、相对时间7 hours ago、千分位逗号1,000,000,000、序数193rd以及英文复数等。本文以该库在本仓库中的 vendored 源码vendor/github.com/dustin/go-humanize为事实依据完整讲解其全部 API、默认行为、底层实现原理与典型使用场景帮助你在自己的 Go 服务中正确选用这些格式化工具。库定位与在本仓库中的依赖形态go-humanize 的核心设计理念正如其 README 所言Just a few functions for helping humanize times and sizes.它不依赖任何第三方运行库纯标准库实现适合嵌入各类 Go 服务。在本仓库中它以indirect 依赖的形式被 vendor 管理go.mod第 196 行声明github.com/dustin/go-humanize v1.0.1 // indirect对应go.sum中的校验记录源码被完整拷贝到 vendor/github.com/dustin/go-humanize/ 目录下包含bytes.go/bigbytes.go字节大小格式化与解析times.go相对时间格式化comma.go/commaf.go千分位数字ftoa.go浮点数格式化si.goSI 记数法ordinals.go序数number.go/big.go通用数字工具english/英文复数与词序列子包若要在自己的项目中使用标准做法是go get github.com/dustin/go-humanize导入路径为github.com/dustin/go-humanize包别名统一为humanize。Sizes字节大小的 SI / IEC 双轨格式化这是该库最常用的能力把82854982这样的裸字节数变成易读的字符串。fmt.Printf(That file is %s., humanize.Bytes(82854982)) // That file is 83 MB.两套进制体系Bytes与IBytes源码bytes.go中同时定义了两种常量体系使用时按业务约定选择体系函数进制常量输出示例82854982SI十进制Bytes1000KByte1000、MByte1000² …EByte83 MBIEC二进制IBytes1024KiByte1024、MiByte1024² …EiByte79 MiBBytes的源码实现非常直白sizes : []string{B, kB, MB, GB, TB, PB, EB}配合humanateBytes内部用对数logn(s, base)求数量级、四舍五入到一位小数小于 10 时保留一位小数否则取整输出。存储介质厂商标称容量通常用 SIBytes操作系统与文件系统通常用 IECIBytes两者混用是磁盘容量缩水争议的根源格式化时务必明确采用哪套标准。反向解析ParseBytesBytes/IBytes的反向操作是ParseBytes可把人类可读字符串解析回字节数// ParseBytes(42 MB) - 42000000, nil // ParseBytes(42 mib) - 44040192, nil从源码看它的解析策略是先扫描字符串头部的数字允许小数点与逗号逗号会被剥离再对剩余后缀做小写化、去空格后查bytesSizeTable映射表。该映射表同时收录了完整后缀kib/kb等、缩写后缀ki/k等和空后缀裸字节因此42 mib、42 Mi、42都能正确解析后缀不识别时返回unhandled size name错误结果溢出uint64时返回too large错误。大数支持当数值超过uint64范围时可使用bigbytes.go中基于math/big的BigBytes/BigIBytes以及big.go中的BigComma等大数版本保证任意精度下依然输出规范格式。Times相对时间的智能分级Time接受一个time.Time返回距现在的人性化描述fmt.Printf(This was touched %s., humanize.Time(someTimeInstance)) // This was touched 7 hours ago.过去的时间自动追加ago未来的时间自动追加from now。其实现times.go定义了一组时间单位常量Day 24 * time.Hour、Week 7 * Day、Month 30 * Day、Year 12 * Month、LongTime 37 * Year——注意这里的月按 30 天、年按 12 个月折算是近似值而非日历概念。默认分级表defaultMagnitudesTime的底层是RelTimeCustomRelTime核心是一张相对时间分级表。每个RelTimeMagnitude结构由三部分组成D切换阈值时长、Format含%s标签位与%d数值位的格式串、DivBy显示数值的除数。默认分级表如下顺序严格递增D阈值输出格式DivBy1 秒now1 秒2 秒1 second %s11 分钟%d seconds %s1 秒2 分钟1 minute %s11 小时%d minutes %s1 分钟2 小时1 hour %s11 天%d hours %s1 小时2 天1 day %s11 周%d days %s1 天2 周1 week %s11 月%d weeks %s1 周2 月1 month %s11 年%d months %s1 月18 月1 year %s12 年2 years %s137 年%d years %s1 年MaxInt64a long while %s1实现上CustomRelTime先计算两时间点差值用二分查找sort.Search定位到第一个D diff的分级随后解析 Format 串中的%s/%d占位符完成替换。得益于这套机制你也可以传入自定义分级表完全定制输出粒度。自定义相对时间RelTime/CustomRelTimeRelTime(a, b, earlier, later)以a、b两个时刻比较较早者用第一个标签CustomRelTime(a, b, albl, blbl, magnitudes)额外传入自定义分级表适合几分钟前/几小时前等产品化需求。Ordinals序数后缀来自 golang-nuts 邮件列表讨论的经典需求把数字转成带序数后缀的字符串。0 - 0th 1 - 1st 2 - 2nd 3 - 3rd 4 - 4th [...]fmt.Printf(Youre my %s best friend., humanize.Ordinal(193)) // You are my 193rd best friend.实现位于 ordinals.go按英文序数规则处理个位与十位的特殊情况如 11/12/13 一律为th可直接用于榜单、排名、楼层号等文案拼接。Commas千分位逗号Comma为int64数字每三位插入逗号并正确处理符号0 - 0 100 - 100 1000 - 1,000 1000000000 - 1,000,000,000 -100000 - -100,000fmt.Printf(You owe $%s.\n, humanize.Comma(6582491)) // You owe $6,582,491.从 comma.go 源码可见两个值得注意的细节math.MinInt64特判最小负整数无法安全取反源码直接返回硬编码的-9,223,372,036,854,775,808负号单独提取主体按三位一组切分并做前导零补齐后以逗号连接。浮点与超大数版本Commaf(v float64)浮点版本commaf.go如Commaf(834142.32) - 834,142.32整数部分加逗号、小数部分原样保留CommafWithDigits(f, decimals)在Commaf基础上限制小数位数如CommafWithDigits(834142.32, 1) - 834,142.3BigComma(b *big.Int)基于math/big的大整数版本big.go循环DivMod千位分组避免int64溢出。Ftoa更干净的浮点数输出fmt.Printf(%f, 2.24)会输出2.240000而humanize.Ftoa会去除多余的尾随零fmt.Printf(%f, 2.24) // 2.240000 fmt.Printf(%s, humanize.Ftoa(2.24)) // 2.24 fmt.Printf(%f, 2.0) // 2.000000 fmt.Printf(%s, humanize.Ftoa(2.0)) // 2实现位于 ftoa.go适合展示配置项数值、统计指标等不希望出现2.240000的界面场景。SI notationSI 记数法格式化SI函数把数字按国际单位制前缀nano/micro/milli/kilo 等格式化humanize.SI(0.00000000223, M) // 2.23 nM实现位于 si.go。它接收一个基准单位字符串根据数量级自动选择合适的前缀——例如上述示例以M为单位即每 1e6 个单位进一位0.00000000223 M就表示2.23 nM。这类函数适合科学计算、传感器数据、性能指标等跨度极大的数值展示。english 子包英文复数与词序列以下函数位于humanize/english子包导入路径为github.com/dustin/go-humanize/english用于英文文案的本地化拼接。Plurals复数english.PluralWord(1, object, ) // object english.PluralWord(42, object, ) // objects english.PluralWord(2, bus, ) // buses english.PluralWord(99, locus, loci) // loci english.Plural(1, object, ) // 1 object english.Plural(42, object, ) // 42 objects english.Plural(2, bus, ) // 2 buses english.Plural(99, locus, loci) // 99 lociPluralWord(count, singular, plural)只返回单词形态内部带bus - buses等规则化处理Plural(count, singular, plural)返回数字 空格 单词的完整短语第三个参数用于提供不规则复数如locus的复数是loci留空则走规则推导。Word series逗号词列表把字符串切片拼接成英文惯用的逗号列表english.WordSeries([]string{foo}, and) // foo english.WordSeries([]string{foo, bar}, and) // foo and bar english.WordSeries([]string{foo, bar, baz}, and) // foo, bar and baz english.OxfordWordSeries([]string{foo, bar, baz}, and) // foo, bar, and baz区别在于OxfordWordSeries遵循牛津逗号规范在最后一个词前额外加逗号foo, bar, and baz适用于通知、权限说明等多元素枚举文案。在本仓库中如何进一步研读源码go-humanize 的全部源码、许可证与文档都随 vendor 机制保留在本仓库中可直接在 vendor/github.com/dustin/go-humanize/ 目录下按需查阅字节格式化与解析的完整常量表、解析错误处理bytes.go相对时间分级表与二分查找实现times.go千分位逗号的MinInt64特判与分组算法comma.go、commaf.go依赖声明与版本锁定go.mod第 196 行v1.0.1 // indirect及go.sum对应哈希小结go-humanize 的实用之处在于把三类最常被机器格式化毁掉可读性的数据——字节大小、时间差、大数字——用十几行函数收敛成统一、可测试的格式化入口。实际使用时只需记住几条原则存储容量选IBytes、厂商容量选Bytes时间展示用Time、需要自定义粒度用CustomRelTime金融或统计数字用Comma/Commaf系列英文文案用english子包。它的实现全部基于标准库无外部依赖在 OpenCloud 这类大型 Go 服务中作为 indirect 依赖被 vendor 管理也正是看中了它小而稳、可审计的特点。【免费下载链接】opencloud️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign.项目地址: https://gitcode.com/GitHub_Trending/op/opencloud创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表