Nil Interface

nil interface 空接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var data interface{} // 定义一个空接口变量

data = 42 // 将整数赋值给接口变量
fmt.Println(data) // 输出 42

data = "hello" // 将字符串赋值给接口变量
fmt.Println(data) // 输出 "hello"

data = []int{1, 2, 3} // 将整数切片赋值给接口变量
fmt.Println(data) // 输出 [1 2 3]

判空操作

试图对一个空接口进行方法调用时,就会引发一个 nil panic,导致程序崩溃。

1
2
3
4
5
func main() {
	var data interface{}
	s := data.(string)
	fmt.Println(s)
}

先判空,避免程序崩溃并增强代码的健壮性。

1
2
3
4
5
6
7
var i interface{}

if s, ok := i.(string); ok {
    fmt.Println(s)
} else {
    fmt.Println("i is not a string")
}

Example of using 空接口变量来实现任意类型的 JSON 序列化和反序列化

因为 JSON 序列化和反序列化需要处理不同类型的数据, 而空接口变量可以存储任何类型的值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import (
    "encoding/json"
    "fmt"
)

func main() {
    // data变量是键为字符串类型,值为任意类型(用空接口实现)的映射(也就是字典或哈希表)
    data := make(map[string]interface{}) 
    //定义map[string]interface{} 类型的变量,并赋值
    data["name"] = "John"  // 此时 interace 是 string
    data["age"] = 30        // 此时 interace 是 int
    data["gender"] = "male"
    // 使用三个不同的 interface{} 类型的值,分别表示姓名、年龄和性别
    jsonStr, err := json.Marshal(data)
    if err != nil {
        fmt.Println("JSON encoding error:", err)
        return
    }
    fmt.Println(string(jsonStr)) // 输出 {"age":30,"gender":"male","name":"John"}
    
    // decodedData变量和 上面 data 相同。
    var decodedData map[string]interface{}
    // 这里使用了指向 decodedData 变量的指针,以便将反序列化后的数据存储到该变量中。
    err = json.Unmarshal(jsonStr, &decodedData)
    if err != nil {
        fmt.Println("JSON decoding error:", err)
        return
    }
    fmt.Println(decodedData) // 输出 map[age:30 gender:male name:John]
}