在 Go 的 struct 中使用指针的坑
資深大佬 : WadeLaunch 27
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: %pn", &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: %pn", &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 的情况?
大佬有話說 (7)