Go 错误:恐慌:运行时错误:无效的内存地址或 nil 指针取消引用。更改存在于另一个结构中的结构内的映射,

分享于2023年04月22日 go 问答
【问题标题】:Go Error: panic: runtime error: invalid memory address or nil pointer dereference. Changing map inside a struct which is present in another struct,Go 错误:恐慌:运行时错误:无效的内存地址或 nil 指针取消引用。更改存在于另一个结构中的结构内的映射,
【发布时间】:2023-04-18 22:10:02
【问题描述】:

我必须构造 struct1 和 struct2,struct2 包含一个带有 struct1 的映射,struct1 也包含一个映射,我想更改 struct1 中存在的映射。

这会引发运行时错误: panic:运行时错误:无效的内存地址或 nil 指针取消引用

type FailureData struct {
    failuresInCommits map[string][]string 
}

type DetectionResults struct {
    Failures map[git_repo.FilePath]*FailureData
        //Have other things
}

func (r *DetectionResults) Fail(filePath git_repo.FilePath, message 
           string, commits []string) {  
        ok := r.Failures[filePath].failuresInCommits //error occurs here    
        if r.Failures[filePath].failuresInCommits == nil {       
            r.Failures[filePath].failuresInCommits = make(map[string][]string)
        }
        if len(ok) == 0 {
            r.Failures[filePath].failuresInCommits[message] = commits
        } else {
            r.Failures[filePath].failuresInCommits[message] = 
               append(r.Failures[filePath].failuresInCommits[message], 
                      commits...)   
        }
}


【解决方案1】:

你写的代码在编译时不会弹出nil错误,只会在你使用错误的时候导致nil point错误。

failuresInCommits map[string][]string 是在 make() 之后使用的吗?

Failures map[git_repo.FilePath]*FailureData 你在'make()'之后用过这个吗?

好的,现在你专注于 ok := r.Failures[filePath].failuresInCommits ,你确定 r.Failures[filePath] 返回'failuresIncommits, true',

如果不是,那么 r.Failures[filePath] 为 nil,好吧,你告诉我 nil.failuresInCommits 是什么。

还有一个风险是你只能在这个特定的包中使用 x.failureInCommits。如果您在其他包中执行相同操作,则 x.failureInCommits 将无法访问,因为字段小写有限。

如何制作?

package main

type FilePath string

type FailureData struct {
    failuresInCommits map[string][]string
}

func NewFailureData() FailureData {
    return FailureData{
        failuresInCommits: make(map[string][]string, 0),
    }
}
func (fd *FailureData) Set(k string, v []string) {
    fd.failuresInCommits[k] = v
}

type DetectionResults struct {
    Failures map[FilePath]*FailureData
    //Have other things
}

func NewDetectionResults() *DetectionResults {
    return &DetectionResults{
        Failures: make(map[FilePath]*FailureData, 0),
    }
}
func (dr *DetectionResults) Set(fp FilePath, fd *FailureData) {
    dr.Failures[fp] = fd
}

func main() {
    fd := NewFailureData()
    dr := NewDetectionResults()
    comments := []string{"push error", "commit error", "add error"}

    fd.Set("hash-18ef8abujce8fad0h8j", comments)
    dr.Set("/etc/go/gopath/src/github.com/xxx/xxx/main.go: 12", &fd)
}

【讨论】:

  • 我有这个函数来创建结构,我无法使用内部结构“*FailureData” func NewDetectionResults() *DetectionResults { result := DetectionResults{make(map[git_repo.FilePath]*FailureData), make(map[git_repo.FilePath][]string) } return &result }
  • @MohammadAbdulBari 我已经刷新了答案以展示如何使用您定义的结构