一句话总结
any 是 interface{} 的官方别名(Go 1.18+),两者完全等价。新代码用 any,老代码不用主动改。
// 标准库源码(builtin/builtin.go)
type any = interface{}
注意是 类型别名(=),不是新类型。编译后字节码完全一样,零成本。
一、为什么 Go 1.18 要加any?
Go 1.18 引入了泛型,类型约束写起来太丑:
// ❌ 老写法
func Print[T interface{}](v T) { ... }
// ✅ 新写法
func Print[T any](v T) { ... }
为了让泛型约束更可读,官方加了 any 这个内置别名,顺手也用在了普通空接口场景。
二、两者的区别
| 维度 | interface{} | any |
|---|---|---|
| 引入版本 | Go 1.0 | Go 1.18+ |
| 本质 | 空接口类型 | interface{} 的别名 |
| 运行时性能 | 完全相同 | 完全相同 |
| 可读性 | 略啰嗦 | 简洁 |
| 标准库使用 | 老代码 | 1.18+ 已全面替换 |
| 工具推荐 | — | gopls、golangci-lint 推荐 |
var a any = 1
var b interface{} = 1
// 完全可以互相赋值,类型断言、反射结果一样
a = b
b = a
三、怎么选?
✅ 用any的场景(推荐 99%)
-
新项目、新代码
func Log(v ...any) { ... } -
泛型约束
func Map[K comparable, V any](m map[K]V) []V { ... } -
变长参数
func Printf(format string, args ...any) { ... } -
map / slice 装混合类型
m := map[string]any{ "name": "alice", "age": 18, }
⚠️ 保留interface{}的少数场景
- 要兼容 Go 1.17 及以下版本(极少见,1.18 已发布多年)
- 改动会污染大量历史代码 / 增加无意义 diff(团队规约)
- 强调"这是一个空接口类型" 而非泛型类型参数
- 公开 API 已经用了 interface{},为了不破坏向后兼容继续保留
四、批量替换工具
Go 官方提供了一键替换工具:
gofmt -r 'interface{} -> any' -w .
或者用 gopls:
gopls codeaction -kind=refactor.rewrite ...
golangci-lint 启用 revive 规则后也会自动提示。
五、常见误区
误区 1:以为any是新类型
var a any
var b interface{}
// a 和 b 是 同一个类型,不是子类型关系
fmt.Printf("%T %T\n", a, b) // <nil> <nil>
误区 2:以为any性能更好
❌ 没有任何区别。底层都是 (type, value) 双指针结构(eface)。
误区 3:以为可以省掉类型断言
不行,从 any 取出具体类型还是要断言:
var v any = 42 n := v.(int) // 类型断言 m, ok := v.(string) // 安全断言
误区 4:以为泛型里any等于comparable
不对:
-
any:任何类型(不能用==比较) -
comparable:可比较类型(能用==)
func Eq[T any](a, b T) bool {
return a == b // ❌ 报错,any 不一定可比较
}
func Eq[T comparable](a, b T) bool {
return a == b // ✅
}
六、实战示例
JSON 解析
var data map[string]any
json.Unmarshal(raw, &data)
if name, ok := data["name"].(string); ok {
fmt.Println(name)
}
泛型容器
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
函数选项模式
type Option func(*Config)
func WithValue(k string, v any) Option {
return func(c *Config) { c.values[k] = v }
}
七、一句话记忆
any = interface{},新代码统一写 any,老代码不用动,性能零差异。 唯一要注意:泛型里 any ≠ comparable,需要 == 比较时用 comparable。













