Golang中Nil不一致性问题解析(已部分解决)
Golang中Nil不一致性问题解析(已部分解决) 你好。
我有以下代码:
var x *t = & .... 更多代码
fmt.Printf("%v, %v\n", x, x == nil)
它打印出:
<nil>, false
我应该从整个问题中提取出关键点,但代码量相当大。这是一个指针,它很可能为 nil,因为解引用时也会引发异常。但我无法通过 nil 检查得到 true。在什么情况下会发生这种情况?
抱歉,我明白了。我把 gcflags 设置成了 -B,并且从一个错误的地方获取了指针。
尽管如此,我还是希望它能告诉我更多“真相”。
更多关于Golang中Nil不一致性问题解析(已部分解决)的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我认为这是因为你将 & 作为值赋给了你的变量。(这将永远不会是 nil)
如果你想将变量赋值为 nil,只需在赋值时传入 nil。(或者返回 nil)
package main
import "fmt"
type t string
func main() {
var x *t
fmt.Printf("%v, %v\n", x, x == nil)
var y t = ""
x = &y
fmt.Printf("%v, %v\n", x, x == nil)
}
输出:
<nil>, true
0xc000014250, false
Go Playground: Go Playground - The Go Programming Language
你是如何得到 <nil>, false 的?你赋值了什么值?
更多关于Golang中Nil不一致性问题解析(已部分解决)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
您说的听起来非常正确,对我来说,它绝不应该返回 nil。所以我实际上并没有太关注这一点。
编译器/运行时之所以说它是 nil,是因为代码是 &something.anotherthing[out_of_bounds_index]。它本应该说“0x23456789,这是一个无效指针”,但它却直接称之为“< nil >”,这是错误的。
我猜想,当使用“-gcflags -B”编译以关闭边界检查时,Go 会让我进入不安全的领域,这完全是我的错,即使运行时在技术上称其为“< nil >”是不正确的。它应该说“< inaccessible >”以免让我困惑,不过现在我已经明白了。
附注:len(something.anotherthing) 是零,所以索引 0 就已经越界了。也许这也有影响。我没有尝试在 Playground 中复现,因为我不知道它是否/如何接受编译器开关。
附注2:这是在 Windows 上发生的。
这是一个典型的Go语言中nil指针与接口类型比较的问题。当接口变量包含一个具体类型的nil指针时,接口本身并不等于nil。
示例代码说明:
package main
import "fmt"
type T struct {
data string
}
func main() {
var x *T = nil
var y interface{} = x
fmt.Printf("x == nil: %v\n", x == nil) // true
fmt.Printf("y == nil: %v\n", y == nil) // false
fmt.Printf("y: %v\n", y) // <nil>
// 类型断言可以正确识别
if ptr, ok := y.(*T); ok && ptr == nil {
fmt.Println("y contains a nil *T pointer")
}
}
输出:
x == nil: true
y == nil: false
y: <nil>
y contains a nil *T pointer
根本原因:接口变量包含两个部分 - 动态类型和动态值。当接口包含一个具体类型的nil指针时,动态类型是*T,动态值是nil,因此接口本身不等于nil。
解决方法:
// 使用反射检查
import "reflect"
func isNilInterface(i interface{}) bool {
return i == nil || reflect.ValueOf(i).IsNil()
}
// 或者在需要时进行类型断言
func process(v interface{}) {
if v == nil {
return
}
// 对具体类型进行处理
if ptr, ok := v.(*T); ok {
if ptr == nil {
// 处理nil指针情况
return
}
// 使用ptr
}
}

