空接口 #

一、空接口概述 #

空接口interface{}(Go 1.18+可写为any)不包含任何方法,因此所有类型都实现了空接口。

二、空接口定义 #

2.1 基本语法 #

go
var x interface{}
var y any  // Go 1.18+

2.2 存储任意类型 #

go
var x interface{}

x = 42
fmt.Printf("%T: %v\n", x, x)  // int: 42

x = "hello"
fmt.Printf("%T: %v\n", x, x)  // string: hello

x = []int{1, 2, 3}
fmt.Printf("%T: %v\n", x, x)  // []int: [1 2 3]

x = map[string]int{"a": 1}
fmt.Printf("%T: %v\n", x, x)  // map[string]int: map[a:1]

2.3 函数参数 #

go
func Print(v interface{}) {
    fmt.Println(v)
}

Print(42)
Print("hello")
Print([]int{1, 2, 3})

三、类型断言 #

3.1 基本语法 #

go
v, ok := x.(T)

3.2 示例 #

go
var x interface{} = "hello"

s, ok := x.(string)
if ok {
    fmt.Println(s)  // hello
}

n, ok := x.(int)
fmt.Println(ok)  // false

3.3 不安全断言 #

go
var x interface{} = "hello"

s := x.(string)  // 正确
fmt.Println(s)

n := x.(int)  // panic: interface conversion

3.4 安全断言 #

go
func process(x interface{}) {
    if s, ok := x.(string); ok {
        fmt.Println("String:", s)
    } else if n, ok := x.(int); ok {
        fmt.Println("Int:", n)
    } else {
        fmt.Println("Unknown type")
    }
}

四、类型switch #

4.1 基本语法 #

go
switch v := x.(type) {
case T:
    // v是T类型
}

4.2 示例 #

go
func TypeOf(x interface{}) string {
    switch v := x.(type) {
    case int:
        return fmt.Sprintf("int: %d", v)
    case string:
        return fmt.Sprintf("string: %s", v)
    case bool:
        return fmt.Sprintf("bool: %v", v)
    case []int:
        return fmt.Sprintf("[]int: %v", v)
    default:
        return fmt.Sprintf("unknown: %T", v)
    }
}

4.3 多类型匹配 #

go
switch v := x.(type) {
case int, int32, int64:
    fmt.Printf("Integer: %v\n", v)
case float32, float64:
    fmt.Printf("Float: %v\n", v)
default:
    fmt.Printf("Other: %T\n", v)
}

4.4 nil检查 #

go
func process(x interface{}) {
    switch v := x.(type) {
    case nil:
        fmt.Println("nil")
    case string:
        fmt.Println("String:", v)
    default:
        fmt.Println("Other:", v)
    }
}

五、实际应用 #

5.1 通用容器 #

go
type Container struct {
    items []interface{}
}

func (c *Container) Add(item interface{}) {
    c.items = append(c.items, item)
}

func (c *Container) Get(index int) interface{} {
    return c.items[index]
}

c := Container{}
c.Add(42)
c.Add("hello")
c.Add([]int{1, 2, 3})

5.2 JSON处理 #

go
func parseJSON(data []byte) (interface{}, error) {
    var result interface{}
    err := json.Unmarshal(data, &result)
    return result, err
}

func processJSON(data []byte) {
    result, _ := parseJSON(data)
    
    switch v := result.(type) {
    case map[string]interface{}:
        fmt.Println("Object:", v)
    case []interface{}:
        fmt.Println("Array:", v)
    default:
        fmt.Println("Other:", v)
    }
}

5.3 函数参数 #

go
func Printf(format string, args ...interface{}) {
    fmt.Printf(format, args...)
}

5.4 配置解析 #

go
type Config map[string]interface{}

func (c Config) GetString(key string) string {
    if v, ok := c[key].(string); ok {
        return v
    }
    return ""
}

func (c Config) GetInt(key string) int {
    if v, ok := c[key].(int); ok {
        return v
    }
    return 0
}

func (c Config) GetSlice(key string) []interface{} {
    if v, ok := c[key].([]interface{}); ok {
        return v
    }
    return nil
}

六、反射 #

6.1 基本用法 #

go
func inspect(x interface{}) {
    t := reflect.TypeOf(x)
    v := reflect.ValueOf(x)
    
    fmt.Printf("Type: %v\n", t)
    fmt.Printf("Value: %v\n", v)
    fmt.Printf("Kind: %v\n", t.Kind())
}

6.2 类型判断 #

go
func isInt(x interface{}) bool {
    return reflect.TypeOf(x).Kind() == reflect.Int
}

6.3 遍历结构体 #

go
func printFields(x interface{}) {
    v := reflect.ValueOf(x)
    t := v.Type()
    
    for i := 0; i < v.NumField(); i++ {
        field := t.Field(i)
        value := v.Field(i)
        fmt.Printf("%s: %v\n", field.Name, value)
    }
}

七、空接口陷阱 #

7.1 类型丢失 #

go
func process(x interface{}) {
    fmt.Printf("%T\n", x)  // 类型信息保留
}

var s []int = []int{1, 2, 3}
process(s)  // []int

7.2 nil处理 #

go
var x interface{}
fmt.Println(x == nil)  // true

var s *string
x = s
fmt.Println(x == nil)  // false(接口值不为nil)

7.3 比较 #

go
var x, y interface{}
x = []int{1, 2, 3}
y = []int{1, 2, 3}
fmt.Println(x == y)  // panic: comparing uncomparable type []int

八、any类型 #

8.1 Go 1.18+ #

go
// any是interface{}的别名
type any = interface{}

var x any
x = 42
x = "hello"

8.2 泛型中的使用 #

go
func Print[T any](v T) {
    fmt.Println(v)
}

九、最佳实践 #

9.1 避免滥用空接口 #

go
// 不好:过度使用空接口
func Process(data interface{}) interface{}

// 好:使用具体类型或接口
func Process(data []byte) error

9.2 使用类型断言 #

go
func process(x interface{}) {
    if s, ok := x.(string); ok {
        fmt.Println(s)
    }
}

9.3 使用类型switch #

go
func process(x interface{}) {
    switch v := x.(type) {
    case int:
        fmt.Println("int:", v)
    case string:
        fmt.Println("string:", v)
    }
}

十、总结 #

空接口要点:

特性 说明
定义 interface{} 或 any
存储 可存储任意类型
断言 x.(T)
类型switch switch x.(type)

关键点:

  1. 任意类型:空接口可存储任意类型
  2. 类型断言:安全断言使用v, ok := x.(T)
  3. 类型switch:处理多种类型
  4. 反射:使用reflect包获取类型信息
  5. 避免滥用:优先使用具体类型或接口

准备好学习Goroutine了吗?让我们进入下一章!

最后更新:2026-03-26