如何使用*指针将数据追加到数组结构中?

huangapple go评论78阅读模式
英文:

How do you append data to array struct with * pointer

问题

我正在学习Go语言的基础知识,遇到了一个可能我理解不够的问题,这段代码运行良好:

package main

import (
	"fmt"
)

type Category struct {
	Id   int
	Name string
}

type Book struct {
	Id         int
	Name       string
	Categories []Category
}

func main() {

	var book Book

	book.Id = 1
	book.Name = "Vanaraj"

	for i := 0; i < 10; i++ {
		book.Categories = append(book.Categories, Category{
			Id:   10,
			Name: "Vanaraj",
		})
	}

	fmt.Println(book)

}

输出
{1 Vanaraj [{10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj}]}

但是在第二段代码中,给 []Category 添加 * 指针会导致程序出错:

package main

import (
	"fmt"
)

type Category struct {
	Id   int
	Name string
}

type Book struct {
	Id         int
	Name       string
	Categories *[]Category
}

func main() {

	var book Book

	book.Id = 1
	book.Name = "Vanaraj"

	for i := 0; i < 10; i++ {
		book.Categories = append(book.Categories, Category{
			Id:   10,
			Name: "Vanaraj",
		})
	}

	fmt.Println(book)

}

输出
./prog.go:26:27: first argument to append must be slice; have *[]Category

现在假设我不能在第二段代码中将 []Category 中的 * 去掉(例如导入的包的情况下),我如何才能像第一段代码那样在 main() 函数中添加代码来追加数据呢?谢谢!

英文:

i'm learning the basics of golang, and i stumbled upon something that i may lack understanding about it, this code works fine:

package main

import (
	&quot;fmt&quot;
)

type Category struct {
	Id   int
	Name string
}

type Book struct {
	Id         int
	Name       string
	Categories []Category
}

func main() {

	var book Book

	book.Id = 1
	book.Name = &quot;Vanaraj&quot;

	for i := 0; i &lt; 10; i++ {
		book.Categories = append(book.Categories, Category{
			Id:   10,
			Name: &quot;Vanaraj&quot;,
		})
	}

	fmt.Println(book)

}

Output:
{1 Vanaraj [{10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj} {10 Vanaraj}]}

But adding * pointer on []Category break the program

package main

import (
	&quot;fmt&quot;
)

type Category struct {
	Id   int
	Name string
}

type Book struct {
	Id         int
	Name       string
	Categories *[]Category
}

func main() {

	var book Book

	book.Id = 1
	book.Name = &quot;Vanaraj&quot;

	for i := 0; i &lt; 10; i++ {
		book.Categories = append(book.Categories, Category{
			Id:   10,
			Name: &quot;Vanaraj&quot;,
		})
	}

	fmt.Println(book)

}

Output:
./prog.go:26:27: first argument to append must be slice; have *[]Category

Now let's say i can't remove the * from []Category on the second block of code (Case example is importing a package), how can i still append data like the first block of the code with only adding codes to my main() function? <br>
Thanks in advance

答案1

得分: 2

与使用int值或*int指针相同。

var p *int

// 需要先初始化指针,例如使用内置的`new()`函数:
p = new(int)

// 对指向的值进行赋值:
*p = 3
fmt.Println(*p)

指针切片也是一样的,需要先初始化指针,例如使用内置的new()函数:

book.Categories = new([]Category)

然后使用*解引用指针:

*book.Categories = append(*book.Categories, Category{
    Id:   10,
    Name: "Vanaraj",
})

Go Playground上尝试一下。

请注意,切片本身已经包含指向底层数组的指针,因此很少需要使用指向切片的指针,通常是不必要的,只会增加复杂性。

英文:

It's the same as using an int value or an *int pointer.

var p *int

You have to initialize it first, e.g. with using the builtin new():

p = new(int)

You assign to the pointed value:

*p = 3
fmt.Println(*p)

The same goes with pointer slices: you first have to initialize it, e.g. with using the builtin new():

book.Categories = new([]Category)

And you dereference the pointer using *:

*book.Categories = append(*book.Categories, Category{
	Id:   10,
	Name: &quot;Vanaraj&quot;,
})

Try it on the Go Playground.

Please note that slices are slice headers which already contain a pointer to a backing array. So using pointers to slices is very rare, usually unneeded and just complicates things.

答案2

得分: 1

func main() {

var book Book

book.Id = 1
book.Name = "Vanaraj"
book.Categories = new([]Category)

for i := 0; i < 10; i++ {
    *book.Categories = append(*book.Categories, Category{
        Id:   10,
        Name: "Vanaraj",
    })
}

fmt.Println(book)}

输出:{1 Vanaraj 0xc00000c030}

要打印类别,您可以使用fmt.Println(book.Categories)

英文:
func main() {

var book Book

book.Id = 1
book.Name = &quot;Vanaraj&quot;
book.Categories = new([]Category)

for i := 0; i &lt; 10; i++ {
    *book.Categories = append(*book.Categories, Category{
        Id:   10,
        Name: &quot;Vanaraj&quot;,
    })
}

fmt.Println(book)}

Ouput : {1 Vanaraj 0xc00000c030}

And to print categories you can use fmt.Println(book.Categories)

huangapple
  • 本文由 发表于 2021年6月1日 17:27:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/67786218.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定