Golang中将自定义类型的切片作为另一种类型的引用

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

Golang Slice of custom Type in another Type as reference

问题

我在我的Go测试代码中遇到了这个错误:

$ go run test.go 
# command-line-arguments
./test.go:43: cannot use &ol1 (type *Orderline) as type Orderline in array element
./test.go:43: cannot use &ol2 (type *Orderline) as type Orderline in array element

代码

package main

import (
	"fmt"
)

type Customer struct {
	Id   int64
	Name string
}

type Order struct {
	Id         int64
	Customer   *Customer
	Orderlines *[]Orderline
}

type Orderline struct {
	Id      int64
	Product *Product
	Amount  int64
}

type Product struct {
	Id      int64
	Modelnr string
	Price   float64
}

func (o *Order) total_amount() float64 {
	return 0.0 // 每个Orderline的总金额收集器在这里
}

func main() {
	c := Customer{1, "Customername"}

	p1 := Product{30, "Z97", 9.95}
	p2 := Product{31, "Z98", 25.00}

	ol1 := Orderline{10, &p1, 2}
	ol2 := Orderline{11, &p2, 6}

	ols := []Orderline{&ol1, &ol2}

	o := Order{1, &c, &ols}

	fmt.Println(o)
}

我还尝试直接向Order的切片中添加元素,但也失败了:

o := new(Order)
o.Id = 1
o.Customer = &c
append(o.Orderlines, &ol1, &ol2)

抛出以下错误:

$ go run test.go 
# command-line-arguments
./test.go:48: append(o.Orderlines, &ol1, &ol2) evaluated but not used
英文:

I get this error with my Go test code:

$ go run test.go 
# command-line-arguments
./test.go:43: cannot use &ol1 (type *Orderline) as type Orderline in array element
./test.go:43: cannot use &ol2 (type *Orderline) as type Orderline in array element

Code

package main

import (
	"fmt"
)

type Customer struct {
	Id int64
	Name string
}

type Order struct {
	Id int64
	Customer *Customer
	Orderlines *[]Orderline
}

type Orderline struct {
	Id int64
	Product *Product
	Amount int64
}

type Product struct {
	Id int64
	Modelnr string
	Price float64
}

func (o *Order) total_amount() float64 {
	return 0.0 // Total amount collector for each Orderline goes here
}

func main() {
	c := Customer{1, "Customername"}
	
	p1 := Product{30, "Z97", 9.95}
	p2 := Product{31, "Z98", 25.00}

	ol1 := Orderline{10, &p1, 2}
	ol2 := Orderline{11, &p2, 6}

	ols := []Orderline{&ol1, &ol2}

	o := Order{1, &c, &ols}

	fmt.Println(o)
}

I also tried to append to the Slice in the Order directly, but it also failed:

o := new(Order)
o.Id = 1
o.Customer = &c
append(o.Orderlines, &ol1, &ol2)

throws:

$ go run test.go 
# command-line-arguments
./test.go:48: append(o.Orderlines, &ol1, &ol2) evaluated but not used

答案1

得分: 4

问题在于你试图将 Orderline 指针放入一个需要 Orderline 值的切片中。

type Order struct {
    Id int64
    Customer *Customer
    Orderlines *[]Orderline
}

将这个字段的类型从

Orderlines *[]Orderline

改为

Orderlines []*Orderline

你还需要将

ols := []Orderline{&ol1, &ol2}

改为

ols := []*Orderline{&ol1, &ol2}

在大多数情况下,定义 *[]slicetype 是多余的,因为切片、映射和通道已经是引用类型。换句话说,如果你将在 main 函数中定义的切片的值传递给一个函数,对复制的切片索引所做的更改将同时改变在 main 函数中定义的原始切片。

然而,需要注意的是,当一个单独的副本的底层数组由于向切片追加数据而被强制增加其容量时,切片之间会解耦。因此,在某些情况下,你可能会发现指向切片的指针是理想的,甚至是必要的。

英文:

The problem is that you are trying to put Orderline pointers into a slice that wants Orderline values.

type Order struct {
    Id int64
    Customer *Customer
    Orderlines *[]Orderline
}

Change this field's type from

Orderlines *[]Orderline

to...

Orderlines []*Orderline

You also need to change...

ols := []Orderline{&ol1, &ol2}

to

ols := []*Orderline{&ol1, &ol2}

In most cases defining a *[]slicetype is redundant because slices, maps, and channels are already reference types. In otherwords if you pass the value of a slice defined in main into a function, changes made to the copied slice's indices will mutate the original slice defined in main as well.

However, it's important to note that slices become decoupled from each other when an individual copy's underlying array is forced to grow it's capacity as a result of appending data to your slice. Therefore in certain scenarios you may find a pointer to a slice ideal or even necessary.

huangapple
  • 本文由 发表于 2014年2月7日 23:47:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/21632032.html
匿名

发表评论

匿名网友

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

确定