go 有关 nil 的一个疑问?

2022 年 10 月 18 日
 yujianwjj

今天突然意识到一个问题:go 的代码中,关于调用结构体指针绑定的方法的时候,方法里面似乎都没有判断该指针是否为 nil 的情况。

type A struct {
	a int
}

func (a *A) Run() {
	fmt.Print(a.a)
}

func TestA(t *testing.T) {
	var a *A
	a.Run()
}

以上代码会报错,原因也很明显,a 为 nil, a.Run() 方法中,访问 a.a 报错。 看了一下自己之前写的所有 go 代码,所有 结构体指针绑定的方法里面,都没有判断是否为 nil 的情况。

4354 次点击
所在节点    Go 编程语言
36 条回复
Adriel
2022 年 10 月 18 日
会 go 不会 go 的都哑口无言了
0o0O0o0O0o
2022 年 10 月 18 日
在一些项目源码里见到过判断的,不过我是觉得没必要。
randm
2022 年 10 月 18 日
会报 panic
coderxy
2022 年 10 月 18 日
if a!=nil ?
hsfzxjy
2022 年 10 月 18 日
这种一般是调用者保证它非 nil
warlock
2022 年 10 月 18 日
这取决于哪里需要关心 a 为 nil 这件事
charmToby
2022 年 10 月 18 日
```golang
type A struct {
a int
}

func (a *A) Run() {
fmt.Print(a.a)
}

func NewA()*A{
return &A{}
}

func TestA(t *testing.T) {
//var a *A // 这一步只是声明了一个变量 a 为 结构体 A 指针类型,没有实例化
//a.Run()
a := NewA() // 一般都是这样去实例化
a.Run()
}
```
XyIsMy
2022 年 10 月 18 日
你这代码只是声明了 变量 a 是 A 类型。没有实例化
fuxiaohei
2022 年 10 月 18 日
判不判断 nil 看需求,有时候结构体绑定的方法是当函数来用的
```golang

import "fmt"

type A struct {
a int
}

func (a *A) Run() {
fmt.Print(a.a)
}

func main() {
var fn = (*A).Run
fmt.Println(fn)
fn(&A{111})
}

```
zhs227
2022 年 10 月 18 日
变量没初始化不能怪函数绑定。
pkoukk
2022 年 10 月 18 日
此时,a==nil
所以,a.Run() == nil.Run()
作为一个 nil,怎么可能执行的了(a *A) Run() 这个函数呢?
这和 go 没有任何关系
JKeita
2022 年 10 月 18 日
你只是声明了个 A 指针类型变量,肯定会报错啊。
tianyou666shen
2022 年 10 月 18 日
家人们 见鬼了
声明变量但不初始化对象 居然不能调用对象方法
CyJaySong
2022 年 10 月 18 日
func TestA(t *testing.T) {
var a = new(A)
a.Run()
}

试试呢😜
zhuweiyou
2022 年 10 月 18 日
要么 new, 要么 &A{} 吧
siloong
2022 年 10 月 18 日
想到了开心的事

```golang
type A struct{}

func (*A) hello() {
fmt.Println("hello, world")
}

func main() {
var a *A
fmt.Printf("a is nil? %v\n", a == nil)
a.hello()
}
```
ArianX
2022 年 10 月 18 日
@pkoukk 是可以执行的,a 是一个有类型的 nil ,可以调用这个类型的指针方法
sardina
2022 年 10 月 18 日
我要调某个结构体的方法,但是我不初始化这个结构体,哎,我就是玩
Citrus
2022 年 10 月 18 日
@siloong 没毛病啊,你的 hello 又没用 A 里的东西,当然能跑。改成这样比较有意思:

type A struct{}

func (*A) hello() {
fmt.Println("hello, world")
}

func main() {
var a *A
var b interface{}
b = a
fmt.Printf("a is nil? %v\n", a == nil)
fmt.Printf("b is nil? %v\n", b == nil)
a.hello()
}
pkoukk
2022 年 10 月 18 日
@ArianX 居然真的可以,涨知识了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/887817

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX