Struct 附加到结构片时内存地址无效或无指针取消引用
以上方法很好Struct 附加到结构片时内存地址无效或无指针取消引用,struct,go,slice,Struct,Go,Slice,以上方法很好 package main import ( "fmt" ) type Person struct { name string } func main() { p := make([]*Person, 0) p = append(p, &Person{"Brian"}) fmt.Println(p[0].name) p = append(p, &Person{"Le Tu"}) fmt.Println
package main
import (
"fmt"
)
type Person struct {
name string
}
func main() {
p := make([]*Person, 0)
p = append(p, &Person{"Brian"})
fmt.Println(p[0].name)
p = append(p, &Person{"Le Tu"})
fmt.Println(p[1].name)
}
上述恐慌
我对append的理解是它隐藏了扩展/添加的机制。显然,我使用append
作为切片“推送”的思维模式是不正确的。有人能解释为什么上面的第二个样本会恐慌吗?为什么我不能只附加我的结构 例如
package main
import (
"fmt"
)
type Person struct {
name string
}
func main() {
p := make([]*Person, 1) //Changed to 1 instead of 0
p = append(p, &Person{"Brian"})
fmt.Println(p[0].name)
p = append(p, &Person{"Le Tu"})
fmt.Println(p[1].name)
}
输出:
package main
import (
"fmt"
)
type Person struct {
name string
}
func main() {
p := make([]*Person, 1) //Changed to 1 instead of 0
fmt.Println(len(p), p)
p = append(p, &Person{"Brian"})
fmt.Println(len(p), p)
fmt.Println(p[1].name)
fmt.Println(p[0])
fmt.Println(p[0].name)
}
1[]
2[0x10500190]
布瑞恩
死机:运行时错误:无效内存地址或零指针取消引用
p
追加前长度为1,追加后长度为2。因此,p[0]
具有未初始化的指针值nil
和p[0]。name
无效
变量函数append将零个或多个值x附加到
类型S,它必须是切片类型,并返回结果切片,
也属于S型
未初始化指针的值为零
以下规则适用于选择器:
4) 如果x是指针类型,且值为nil,且x.f表示结构字段,则为x.f赋值或求值会导致运行时死机
使用make
构建切片时,第一个整数参数是所创建切片的实际长度:
1 [<nil>]
2 [<nil> 0x10500190]
Brian
<nil>
panic: runtime error: invalid memory address or nil pointer dereference
关于如何使用这两种情况的简单示例:
p := make([]*Person, 0, 100) //<- slice of length 0, but the first 100 append
// won't reallocate the slice
//100单元切片:
p1:=制造([]*人,100)
对于i:=0;i<100;i++{
名称:=fmt.Sprintf(“Foo%d”,i+1)
//您可以访问并分配给p1[i],因为p1有100个单元格:
p1[i]=&个人{name}
}
fmt.Printf(“p1[0]。名称:%s\n”,p1[0]。名称)
fmt.Printf(“p1[99]。名称:%s\n”,p1[99]。名称)
//0单元,100容量片:
p2:=制造([]*人,0,100)
对于i:=0;i<100;i++{
名称:=fmt.Sprintf(“Foo%d”,i+1)
//您无法访问p2[i],该单元格尚不存在:
p2=追加(p2,&个人{name})
}
fmt.Printf(“p2[0]。名称:%s\n”,p2[0]。名称)
fmt.Printf(“p2[99]。名称:%s\n”,p2[99]。名称)
p := make([]*Person, 0, 100) //<- slice of length 0, but the first 100 append
// won't reallocate the slice
//100-cell slice :
p1 := make([]*Person, 100)
for i := 0; i < 100; i++ {
name := fmt.Sprintf("Foo %d", i+1)
//you can access and assign to p1[i] because p1 has 100 cells :
p1[i] = &Person{name}
}
fmt.Printf("p1[0].Name : %s\n", p1[0].Name)
fmt.Printf("p1[99].Name : %s\n", p1[99].Name)
//0-cell, 100-capacity slice :
p2 := make([]*Person, 0, 100)
for i := 0; i < 100; i++ {
name := fmt.Sprintf("Foo %d", i+1)
//you cannot access p2[i], the cell doesn't exist yet :
p2 = append(p2, &Person{name})
}
fmt.Printf("p2[0].Name : %s\n", p2[0].Name)
fmt.Printf("p2[99].Name : %s\n", p2[99].Name)