Golang中指针与接口的赋值问题:A = nil、A = B 且 B != nil 的情况分析
Golang中指针与接口的赋值问题:A = nil、A = B 且 B != nil 的情况分析
你使用的Go版本是什么(go version)?
Go Playground上的版本
这个问题在最新版本中是否重现?
如果Go Playground是最新版本,那么是的
你使用的操作系统和处理器架构是什么(go env)?
不适用
你做了什么?
https://play.golang.org/p/jM2mOSkKo-a
你期望看到什么?
期望打印以下内容之一:
interfaceSlice[1] == ps[1]
ps[1] == nil
interfaceSlice[1] == nil
或者仅打印:
ps[1] == nil
实际看到了什么?
实际打印:
ps[1] == nil
interfaceSlice[1] == ps[1]
我想了解导致这种情况的原因
更多关于Golang中指针与接口的赋值问题:A = nil、A = B 且 B != nil 的情况分析的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
感谢乔恩,我认为你的回答中唯一缺少的细节是:当左操作数没有显式类型时(如 12 或 nil),等号运算符会假定其类型与右操作数相同。
更多关于Golang中指针与接口的赋值问题:A = nil、A = B 且 B != nil 的情况分析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个关于Go语言中接口和指针赋值行为的经典问题。让我通过代码示例来解释这个现象:
package main
import "fmt"
type Person struct {
Name string
}
func main() {
var interfaceSlice []interface{}
var ps []*Person
// 情况1: 直接赋值nil
ps = append(ps, nil)
interfaceSlice = append(interfaceSlice, ps[0])
// 情况2: 通过指针变量赋值
var p *Person = nil
ps = append(ps, p)
interfaceSlice = append(interfaceSlice, ps[1])
fmt.Printf("ps[0] == nil: %t\n", ps[0] == nil)
fmt.Printf("interfaceSlice[0] == nil: %t\n", interfaceSlice[0] == nil)
fmt.Printf("interfaceSlice[0] == ps[0]: %t\n", interfaceSlice[0] == ps[0])
fmt.Printf("ps[1] == nil: %t\n", ps[1] == nil)
fmt.Printf("interfaceSlice[1] == nil: %t\n", interfaceSlice[1] == nil)
fmt.Printf("interfaceSlice[1] == ps[1]: %t\n", interfaceSlice[1] == ps[1])
}
原因分析:
-
接口的nil判断机制:
- 一个接口值由两部分组成:类型(type)和值(value)
- 只有当类型和值都为nil时,接口才等于nil
- 当你将一个具体类型的nil指针赋给接口时,接口的类型信息被设置为
*Person,值被设置为nil
-
代码执行逻辑:
// ps[1]是*Person类型的nil指针 ps[1] == nil // true,因为这是具体类型的nil比较 // interfaceSlice[1]是interface{}类型,包含(*Person, nil) interfaceSlice[1] == nil // false,因为类型不是nil interfaceSlice[1] == ps[1] // true,因为两者都包含相同的类型和值 -
更清晰的示例:
var p *Person = nil
var i interface{} = p
fmt.Printf("p == nil: %t\n", p == nil) // true
fmt.Printf("i == nil: %t\n", i == nil) // false
fmt.Printf("i == p: %t\n", i == p) // true
这就是为什么你会看到ps[1] == nil为true,而interfaceSlice[1] == nil为false,但两者比较却相等的原因。接口保持了原始指针的类型信息,即使其值为nil。

