首页 > 编程开发 > Go语言    日期:2026-08-19 / 浏览

一句话总结

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%)

  1. 新项目、新代码

    func Log(v ...any) { ... }
    
  2. 泛型约束

    func Map[K comparable, V any](m map[K]V) []V { ... }
    
  3. 变长参数

    func Printf(format string, args ...any) { ... }
    
  4. map / slice 装混合类型

    m := map[string]any{
        "name": "alice",
        "age":  18,
    }
    

⚠️ 保留interface{}的少数场景

  1. 要兼容 Go 1.17 及以下版本(极少见,1.18 已发布多年)
  2. 改动会污染大量历史代码 / 增加无意义 diff(团队规约)
  3. 强调"这是一个空接口类型" 而非泛型类型参数
  4. 公开 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。

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章

1 2 3 4 5