最直接的方法是用 strings.split 拆分行再遍历每行 len() 得字节长度;需注意 utf-8 字节与 unicode 码点区别,末尾换行符产生空行,windows 换行符需预处理,超大文本应改用 strings.scanner 流式读取。

用 strings.Split 拆分行再遍历长度最直接
Go 没有内置的“按行统计字符数”函数,但 strings.Split 是最贴近需求的起点。它把字符串按 \n 切成 []string,之后对每个元素调用 len() 即可——注意这里统计的是 UTF-8 字节数,不是 Unicode 码点数(中文、emoji 都算多个字节)。
常见错误是直接用 strings.Count(s, "\n") 估算行数,但无法获取每行长度;或者误用 utf8.RuneCountInString 统计整串码点数,和“每行字符数”完全不匹配。
- 如果文本末尾有换行符,
strings.Split会产生一个空字符串结尾项,需判断line != ""过滤 - Windows 换行符
\r\n会被当成普通字符处理,\r算进当前行长度;如需兼容,先用strings.ReplaceAll(s, "\r\n", "\n") - 性能上,
strings.Split会分配新字符串切片,对超大文本(GB 级)建议改用strings.Scanner流式处理
用 strings.Scanner 处理超长文本避免内存暴涨
当输入可能达几十 MB 或来自 io.Reader(比如文件或网络流),一次性加载到内存再 Split 容易 OOM。strings.Scanner 能逐行读取,每行只保留当前内容,内存占用稳定。
注意:默认 Scanner 以 \n 为分隔符,不自动 strip \r;若源数据含 \r\n,需手动 trim 或设置自定义分隔符:
scanner := bufio.NewScanner(strings.NewReader(text))
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := scanner.Text() // 已自动去掉 \n,但 \r 还在
length := len(line)
// ...
}
-
scanner.Text()返回的是副本,修改它不影响后续行 - 如果某行超长(> 64KB),
scanner.Scan()会返回 false 并报错bufio.Scanner: token too long;可通过scanner.Buffer(make([]byte, 4096), 1 扩容缓冲区 - 不要混用
scanner.Bytes()和scanner.Text(),前者返回底层 slice,后者返回 string,两者底层数据生命周期不同
区分字节长度和 Unicode 字符数(rune 数)
中文、emoji、带重音符号的字母在 Go 中占多个字节,但通常业务说的“字符数”指人眼看到的“字”个数,即 rune 数。这时不能用 len(line),得用 utf8.RuneCountInString(line)。
例如:"??" 是一个 emoji 组合,占 4 个字节(UTF-8 编码),但只有 1 个 rune;"你好" 是 6 字节,2 个 rune。
- 性能差异明显:
len()是 O(1),utf8.RuneCountInString()是 O(n),对纯 ASCII 文本没必要用 - 如果只要“可视字符数”,且文本含 emoji 或多语言,必须用 rune 计数;否则按字节计数更高效也更符合底层存储逻辑
- 没有“万能函数”同时兼顾速度和语义准确性,得根据实际场景选:日志分析常看字节长度,前端展示计数常看 rune 数
一行代码快速验证:用 strings.FieldsFunc 做无副作用预处理
如果原始文本有多余空行或首尾空白,又不想污染原逻辑,可用 strings.FieldsFunc 预过滤。它按自定义函数切分,比 Split 更灵活:
lines := strings.FieldsFunc(text, func(r rune) bool {
return r == '\n' || r == '\r'
})
// lines 不含空行,也不含 \r\n 残留
但要注意:FieldsFunc 会跳过所有连续分隔符(如 \n\n 变成一个空隙),结果里不会出现空字符串;如果业务需要保留空行,就不能用它。
- 这个技巧适合配置文件解析、命令行输入清洗等场景
- 函数参数必须是
rune类型,不能传byte;'\n'字面量会被自动转为 rune - 它不修改原字符串,也不分配额外字符串,只是生成切片头,开销极小
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











