[Go 编程语言] 在 Go 的 struct 中使用指针的坑

go version: go1.17.3 linux/amd64
package main import ( "fmt"
) // 注意 Row 的字段是指针类型
type Row struct { Id *int Open *bool
} type Source struct { Id int Open bool
} func main() { sourceList := []Source{ {Id: 1, Open: true}, {Id: 2, Open: false}, } var rows []Row for _, v := range sourceList { fmt.Println("sourceList.v:") fmt.Printf(" &v.%%p: %p\n", &v) fmt.Println(" &v:", &v) fmt.Println(" v:", v) fmt.Println(" &v.Id:", &v.Id) fmt.Println(" v.Id:", v.Id) fmt.Println(" &v.Open:", &v.Open) fmt.Println(" v.Open:", v.Open) rows = append(rows, Row{Id: &v.Id, Open: &v.Open}) } fmt.Println("\nrows, len", rows, len(rows)) for _, v := range rows { fmt.Println("rows.v:") fmt.Printf(" &v.%%p: %p\n", &v) fmt.Println(" v.Id:", v.Id) fmt.Println(" *v.Id:", *v.Id) fmt.Println(" v.Open:", v.Open) fmt.Println(" *v.Open:", *v.Open) }
}

先不看下面的答案,猜猜 rows 的结果是什么?

先不看下面的答案,猜猜 rows 的结果是什么?

先不看下面的答案,猜猜 rows 的结果是什么?

答案揭晓:

sourceList.v: &v.%p: 0xc0000aa000 &v: &{1 true} v: {1 true} &v.Id: 0xc0000aa000 v.Id: 1 &v.Open: 0xc0000aa008 v.Open: true
sourceList.v: &v.%p: 0xc0000aa000 &v: &{2 false} v: {2 false} &v.Id: 0xc0000aa000 v.Id: 2 &v.Open: 0xc0000aa008 v.Open: false rows, len [{0xc0000aa000 0xc0000aa008} {0xc0000aa000 0xc0000aa008}] 2
rows.v: &v.%p: 0xc00008c240 v.Id: 0xc0000aa000 *v.Id: 2 v.Open: 0xc0000aa008 *v.Open: false
rows.v: &v.%p: 0xc00008c240 v.Id: 0xc0000aa000 *v.Id: 2 v.Open: 0xc0000aa008 *v.Open: false

问题一:为什么 rows 两行值是一样的?(我自己有一个答案,可能是错的,先不写出来,想先问问大家的看法)

问题二:初学 Go ,请问在 struct 中用指针是不推荐的用法吗?还是我不会用?

这个用法是在某个框架中看到的,用指针可能是为了通过 if Row.Id != nil 来区分请求参数不存在(domain/path?name=x)与请求参数的值是 0 (domain/path?name=x&id=0) 的情况。

问题三:怎么区分这种参数不存在与参数值是 0 的情况?

发表评论

您的电子邮箱地址不会被公开。