go语言中len是内置函数而非方法,仅支持切片、数组、map、字符串和channel;字符串len返回字节数非字符数,需utf8.runecountinstring获取rune数;自定义类型须定义大写len()方法以满足接口契约。

Go 语言没有 Len 函数,只有内置的 len 函数;自定义类型也不能重载 len,但可实现 Len() 方法来提供长度逻辑。
len 是函数,不是方法:调用写法必须是 len(x),不是 x.len()
很多从 Java、Python 或 JavaScript 转来的开发者会下意识写 x.len(),结果编译失败,报错:type []int has no field or method len。这是因为 len 是编译器内置函数,不归属任何类型,也不支持点号调用。
-
len只接受参数,如len(s)、len(m)、len(str) - 对切片、数组、map、string、channel 有效;对 struct、自定义类型直接传参会编译错误
- 它在编译期或运行时直接读取底层结构字段(比如切片头里的
len字段),零开销
字符串长度:len(str) 返回字节数,不是字符数
这是线上 bug 高发区。例如 len("你好") 返回 6,因为 UTF-8 下每个中文占 3 字节;len("??") 可能返回 11(含 ZWJ 连接符)。如果你在做 UI 截断、分页、光标定位,用 len 就会出乱码或崩溃。
- 要获取 Unicode 字符(rune)数量,用
utf8.RuneCountInString(str) - 若已需频繁操作字符,可转成
[]rune后用len([]rune(str)),但注意会额外分配内存 - 截取前 N 个字符不能写
str[:n],应写string([]rune(str)[:n])
自定义类型想暴露长度?必须定义 Len() 方法
Go 不允许你“重载”len,但标准库和生态广泛约定:给类型加一个导出的 Len() 方法。这不是语法强制,而是接口契约(如 sort.Interface 就要求 Len() int)。
- 方法名必须是
Len(首字母大写),返回int - 内部可安全访问未导出字段,比如封装了
data []string,就 returnlen(t.data) - 别写成
len()(小写),Go 接口匹配靠名字+签名,sort.Interface明确要求大写Len - 示例:
type Queue struct{ items []int }→func (q *Queue) Len() int { return len(q.items) }
cap 和 append 常与 len 搭配,但用途完全不同
新手容易混淆三者关系:len 是当前元素数,cap 是底层数组还能塞多少,append 是追加并可能触发扩容。它们常一起出现,但语义不可互换。
-
len(s) == cap(s)表示切片已满,下次append必定分配新底层数组 - 预分配惯用法:
result := make([]string, 0, len(src)),再循环append(result, item),避免多次 realloc -
s = s[:0]不改变cap,只是把len归零,适合复用底层数组
最易被忽略的是:字符串的 len 和 utf8.RuneCountInString 在性能和语义上完全不可互换;而自定义类型的 Len() 方法一旦命名错误(比如写成 len() 或 Length()),就会导致 sort.Sort 等标准库调用静默失败——它不会报错,只是按 0 处理,结果全乱。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











