dongzhang5006 2014-06-15 12:39
浏览 29
已采纳

范围超过结构片时的Golang内存地址问题

I am very new to Go so there is probably a very simple fix for this. I am having trouble calling a method of an interface that is within a struct in an array. I think this is best explained through an example, so here is the most basic example I was able to boil my code down to.

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())
    }
} 

When I try to execute this, I get the following error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x400efd]

How do I properly call Hello while looping through the array in this setup?

  • 写回答

1条回答 默认 最新

  • dongyo1818 2014-06-15 13:00
    关注

    Your problem is in the line

     t := make(TestList, 1, 100)
    

    Here, you've initialized t to already have one TestRecord in it, but you didn't set any of the fields in that TestRecord, so t[0].test is nil. You can't call methods on a nil interface, because Go doesn't know what method to call.

    The simplest fix (the one that changes your source code the least) is to start with an empty TestList, using the following statement:

    t := make(TestList, 0, 100)
    

    However, if you wish, you can also rely on append to allocate t as necessary, and start with a nil TestList by declaring t as follows:

    var t TestList
    

    (I recommend the second version in your test program, since you're not using the full capacity anyway, however I recognize that you may have condensed this from a real program where specifying the capacity in advance is actually helpful.)


    Calling methods on a nil value

    • You can call methods on a nil struct pointer, because Go can determine what function should be called at compile time. However, if that function dereferences the struct pointer, then you'll get this same crash at the site of the dereference.
    • When you're accessing this pointer through an interface, Go needs to dereference it to figure out which function to call, so the program crashes as soon as you make the function call.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据