我是Go的新手,所以可能有一个非常简单的解决方法.我在调用数组结构中的接口方法时遇到问题.我认为最好通过一个例子来解释,所以这里是我能够将代码简化为最基本的例子.
package main
import "fmt"
/* Test Types */
type Test interface {
Hello() string
}
type TestRecord struct {
test Test
name string
}
type TestList []TestRecord
/* Other Type */
type Other struct{}
func (o Other) Hello() string {
return "Hello From Other"
}
func main() {
/* Init TestList into t */
t := make(TestList, 1, 100)
/* Create TestRecord and add it to the list */
tr := TestRecord{Other{}, "OtherRecord"}
t = append(t, tr)
/* Loop over list and */
for _, otr := range t {
fmt.Println(otr.name)
fmt.Println(otr.test.Hello())
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试执行此操作时,出现以下错误:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x400efd]
Run Code Online (Sandbox Code Playgroud)
如何在此设置中循环遍历数组时正确调用Hello?
你的问题就在于此
t := make(TestList, 1, 100)
Run Code Online (Sandbox Code Playgroud)
在这里,你已经初始化吨至已经有一个TestRecord在里面,但你没有设置任何在该领域TestRecord,所以t[0].test是nil.你不能在nil接口上调用方法,因为Go不知道要调用什么方法.
最简单的修复(最少改变源代码的修复)是TestList使用以下语句从空开始:
t := make(TestList, 0, 100)
Run Code Online (Sandbox Code Playgroud)
但是,如果您愿意,您也可以依赖于必要时append进行分配t,并nil TestList以声明t如下开头:
var t TestList
Run Code Online (Sandbox Code Playgroud)
(我建议您在测试程序中使用第二个版本,因为您还没有使用完整容量,但是我知道您可能已经从实际程序中浓缩了这个,其中预先指定容量实际上是有帮助的.)
nil 结构指针上调用方法,因为Go可以确定在编译时应该调用哪个函数.但是,如果该函数取消引用结构指针,那么您将在取消引用的站点上获得同样的崩溃.| 归档时间: |
|
| 查看次数: |
1155 次 |
| 最近记录: |