go 结构体内嵌接口的疑问

2021-03-19 14:43:36 +08:00
 yujianwjj
func TestInterface(t *testing.T) {
	type Reader interface {
		Read()
	}
	type Cache struct {
		Reader
	}
	c := Cache{}
	c.Read()
}

以上代码会报空指针错误。

我的疑问是,有没有办法在编译的时候就能够主动的发现这个错误。

1565 次点击
所在节点    Go 编程语言
10 条回复
baiyi
2021-03-19 15:01:31 +08:00
结构体如果是实现接口,可以通过 var _ Reader = Cache{} 来发现。

内嵌只能通过 if c.Reader != nil 来判断了吧,编译器并不知道你在哪里赋值了。
hwdef
2021-03-19 15:10:00 +08:00
https://github.com/xxjwxc/uber_go_guide_cn

可以看看 uber 的 go 风格指南,我记得有写
Mark3K
2021-03-19 15:12:26 +08:00
内嵌 interface 的目的是啥
rrfeng
2021-03-19 15:16:32 +08:00
你这个
type Cache struct {
Reader
}
等于
type Cache struct {
Reader Reader
}

然后 Cache{} 初始化时,接口类型默认值是 nil,所以 Reader 是 nil

跟下面一个道理(指针类型的默认值是 nil )
type Cache Struct {
Something *int
}


所以,无解。通常写一个 NewCache() 方法生成可以避免。
kele1997
2021-03-19 15:20:03 +08:00
`var _ Reader = (*Cache)(nil)`
kele1997
2021-03-19 15:27:00 +08:00
不好意思,俺上面的写法是针对,实现接口的。你问题里面的是直接继承接口。
不过你可以不继承接口,然后使用下面的代码来实现

```
func TestInterface(t *testing.T) {
type Reader interface {
Read()
}
type Cache struct {
}


var _ Reader = (*Cache)(nil)
c := Cache{}
c.Read()
}
```
janxin
2021-03-19 15:29:43 +08:00
@rrfeng 正解,不过即便写了 NewCache()也没法杜绝 SB 用户这么用🤦‍♂️
nuk
2021-03-19 15:38:15 +08:00
不能,所以不要把 interface 嵌入 struct
fenghuang
2021-03-19 23:22:54 +08:00
把 struct 匿名嵌套在 struct 也会出现这种情况
qwertyzzz
2021-03-20 14:25:58 +08:00
这个问题我怎么在哪见过啊

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

https://www.v2ex.com/t/763204

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

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

© 2021 V2EX