Golang中无法将append(*pairs, Pair literal) (类型Pairs)作为类型*Pairs赋值的问题

Golang中无法将append(pairs, Pair literal) (类型Pairs)作为类型Pairs赋值的问题 我正在编写一段代码来处理 warehouse[item[batch, qty]] 的组合,然后根据 batch[batch, qty] 进行分组并计算 qty 的总和。我的代码如下:

package main

import "fmt"

type Inventory struct {   //instead of: map[string]map[string]Pairs
	Warehouse string
	Item      string
	Batches   Pairs
} 
type Pairs []Pair
type Pair struct {
	Key   string
	Value float64
}

func main() {
	fmt.Println("Hello, 世界")
	var inventory = Inventory{} // or: new(Inventory) noth are working //warehouse[item[batch, qty]]
	inventory.Warehouse = "DMM"
	inventory.Item = "Helmet"
	inventory.Batches = append(inventory.Batches, Pair{"Jan", 10})
	inventory.Batches = append(inventory.Batches, Pair{"Jan", 30})
	inventory.Batches = append(inventory.Batches, Pair{"Feb", 30})
	fmt.Printf("%v\n", inventory)
	inventory.Batches.group()
}

func (p *Pairs) group() {
	sum := make(map[string]float64)
	pairs := new(Pairs)
	for _, el := range *p {
		sum[el.Key] = sum[el.Key] + el.Value
	}
	fmt.Printf("%v %T\n", sum, sum)
	for k, v := range sum {
		pairs = append(*pairs, Pair{k, v})     // <--------------- here is the error
	}
	fmt.Printf("%v %T\n", pairs, pairs)
}

但在分组时我遇到了提到的错误:

# _/C_/Users/HASAN~1.YOU/AppData/Local/Temp/present-048467841
.\prog.go:36:9: cannot use append(*pairs, Pair literal) (type Pairs) as type *Pairs in assignment

Program exited: exit status 2

更多关于Golang中无法将append(*pairs, Pair literal) (类型Pairs)作为类型*Pairs赋值的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我找到了答案,有两种可能的解决方案:

  1. pairs 定义为 var pairs Pairs,这定义的是 Pairs 类型,而不是 pairs := new(Pairs),后者定义的是 *Pairs 类型。
  2. 在赋值语句的两边对 pairs 进行解引用,改为:*pairs = append(*pairs, Pair{k, v})

所以,现在对我来说完整可运行的代码如下:

package main

import "fmt"

type Inventory struct { //instead of: map[string]map[string]Pairs
	Warehouse string
	Item      string
	Batches   Pairs
}
type Pairs []Pair
type Pair struct {
	Key   string
	Value float64
}

func main() {
	fmt.Println("Hello, 世界")
	var inventory = Inventory{} // or: new(Inventory) noth are working //warehouse[item[batch, qty]]
	inventory.Warehouse = "DMM"
	inventory.Item = "Helmet"
	inventory.Batches = append(inventory.Batches, Pair{"Jan", 10})
	inventory.Batches = append(inventory.Batches, Pair{"Jan", 30})
	inventory.Batches = append(inventory.Batches, Pair{"Feb", 30})
	fmt.Printf("%v\n", inventory)
	result := inventory.Batches.group()
	fmt.Printf("%v %T\n", result, result)
}

func (p *Pairs) group() Pairs {
	sum := make(map[string]float64)
	pairs := new(Pairs)
	// var pairs Pairs
	for _, el := range *p {
		sum[el.Key] = sum[el.Key] + el.Value
	}
	for k, v := range sum {
		*pairs = append(*pairs, Pair{k, v}) // with pairs := new(Pairs)
		// pairs = append(pairs, Pair{k, v})   // var pairs Pairs
	}
	return *pairs
}

输出结果是:

Hello, 世界
{DMM Helmet [{Jan 10} {Jan 30} {Feb 30}]}
[{Jan 40} {Feb 30}] main.Pairs

Program exited.

更多关于Golang中无法将append(*pairs, Pair literal) (类型Pairs)作为类型*Pairs赋值的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在 pairs 变量的类型声明和 append 函数的返回值类型不匹配。pairs 被声明为 *Pairs 指针类型,但 append 返回的是 Pairs 值类型。

这里有几种解决方案:

方案1:直接使用值类型(推荐)

func (p *Pairs) group() {
    sum := make(map[string]float64)
    var pairs Pairs  // 改为值类型
    
    for _, el := range *p {
        sum[el.Key] = sum[el.Key] + el.Value
    }
    
    for k, v := range sum {
        pairs = append(pairs, Pair{k, v})  // 现在类型匹配
    }
    
    *p = pairs  // 更新原始数据
    fmt.Printf("%v %T\n", pairs, pairs)
}

方案2:保持指针类型但正确使用

func (p *Pairs) group() {
    sum := make(map[string]float64)
    pairs := &Pairs{}  // 创建指针
    
    for _, el := range *p {
        sum[el.Key] = sum[el.Key] + el.Value
    }
    
    for k, v := range sum {
        *pairs = append(*pairs, Pair{k, v})  // 解引用指针
    }
    
    *p = *pairs  // 更新原始数据
    fmt.Printf("%v %T\n", pairs, pairs)
}

方案3:更简洁的实现

func (p *Pairs) group() {
    sum := make(map[string]float64)
    
    // 计算总和
    for _, el := range *p {
        sum[el.Key] += el.Value
    }
    
    // 清空并重新填充
    *p = (*p)[:0]
    for k, v := range sum {
        *p = append(*p, Pair{k, v})
    }
    
    fmt.Printf("%v %T\n", p, p)
}

完整修正示例

func (p *Pairs) group() {
    sum := make(map[string]float64)
    
    // 分组求和
    for _, pair := range *p {
        sum[pair.Key] += pair.Value
    }
    
    // 创建新的Pairs并替换原数据
    var grouped Pairs
    for key, total := range sum {
        grouped = append(grouped, Pair{key, total})
    }
    
    *p = grouped
    fmt.Printf("分组后: %v\n", *p)
}

关键点:append 函数返回的是切片值,不是指针。当需要更新指针指向的切片时,需要通过解引用操作 *p = newValue 来赋值。

回到顶部