2012-02-27 71 views
2

我不知道我该如何构建这个示例代码,以帮助避免空指针引用恐慌:如何避免“无效的内存地址或空指针取消引用”错误?

package main 

import "fmt" 

type Astruct struct { 
    Number int 
    Letter string 
} 

type Bstruct struct { 
    foo int 
    AStructList *[]Astruct 
} 

type Cstruct struct { 
    Bstruct 
} 

func (a *Astruct) String() string { 
    return fmt.Sprintf("Number = %d, Letter = %s", a.Number, a.Letter) 
} 

func main() { 
    astructlist := make([]Astruct, 3)  // line 1 
    for i := range astructlist {   // line 2 
     astructlist[i] = Astruct{i, "a"} // line 3 
    }          // line 4 
    c := new(Cstruct) 
    c.Bstruct = Bstruct{100, &astructlist} // line 6 

    for _, x := range(*c.Bstruct.AStructList) { 
     fmt.Printf("%s\n", &x) 
    } 
} 

如果我省略1-4行和主()6,我得到一个空指针引用恐慌。检查c!= nil是否有办法避免这些恐慌?

在此先感谢您的帮助!

+0

你的问题不是'c'是一个零指针,而是'c.Bstruct.AStructList'是一个零指针 – newacct 2012-02-27 23:13:52

+0

是的。我明白错误来自哪里,但是我想知道的(也许在原始问题中没有说清楚)是“是否有更好/更习惯的方法来避免这个问题?”我花了一些时间看代码,并且认为必须有更好的方法来构造结构,以避免遇到零指针问题。 – mtw 2012-02-27 23:25:50

回答

6

在这种特殊情况下,您可以使用惯用的Go。将AStructList *[]Astruct更改为AStructList []*Astruct。例如,

package main 

import "fmt" 

type Astruct struct { 
    Number int 
    Letter string 
} 

type Bstruct struct { 
    foo   int 
    AStructList []*Astruct 
} 

type Cstruct struct { 
    Bstruct 
} 

func (a *Astruct) String() string { 
    return fmt.Sprintf("Number = %d, Letter = %s", a.Number, a.Letter) 
} 

func main() { 
    astructlist := make([]*Astruct, 3)   // line 1 
    for i := range astructlist {     // line 2 
     astructlist[i] = &Astruct{i, "a"}   // line 3 
    }            // line 4 
    c := new(Cstruct) 
    c.Bstruct = Bstruct{100, astructlist}   // line 6 

    for _, x := range c.Bstruct.AStructList { 
     fmt.Printf("%s\n", x) 
    } 
} 

一般情况下,这是你的责任,要么在使用前分配非nil值的指针或测试nil。当你没有显式初始化分配内存时,它被设置为该类型的零值,对于指针是nil

The zero value

当内存分配给存储的值,无论是通过 声明或品牌或新的呼叫,并没有明确的初始化 提供,内存指定缺省初始化。每个 这样一个元素的值被设置为零值,其类型为:布尔值为false ,整数为0,浮点值为0.0,字符串为“”,字符串为零,指针,函数,接口,切片,通道和零值为零,为 。地图。这个初始化是递归地完成的,例如,如果没有指定值,那么 结构数组的每个元素都将其字段置零。

+0

嗨peterSO,这正是我正在寻找的。我没有意识到我可以将Bstruct.AStructList定义为一个指针片,而不是指向Astructs片的指针。干杯! – mtw 2012-02-27 23:26:09

相关问题