为了账号安全,请及时绑定邮箱和手机立即绑定

在结构方法中更改后设置为零的指针值

在结构方法中更改后设置为零的指针值

Go
一只萌萌小番薯 2022-08-01 17:29:57
这是我的代码:type Cake struct {    weight      int    value       int    costBenefit float32}func (c *Cake) SetCostBenefit() float32 {    if c.costBenefit == 0 {        c.costBenefit = float32(c.value) / float32(c.weight)    }    return c.costBenefit}func main() {    capacity := 20    cakes := []Cake{{weight: 7, value: 160}, {weight: 3, value: 90}, {weight: 2, value: 15}}    result := maxDuffelBagValue(cakes, capacity)    fmt.Printf("Max capacity %d", result)}func maxDuffelBagValue(cakes []Cake, capacity int) int {    calcCostBenefit(&cakes)    for _, c := range cakes {        fmt.Printf("Value Cake cost benefit 2: %v \n", c.costBenefit)    }    return 0}func calcCostBenefit(cakes *[]Cake) {    for _, c := range *cakes {        c.SetCostBenefit()        fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)    }}正如您在上面看到的,我有一个结构方法,用于设置结构蛋糕的 CostBenefit 属性。由于我将蛋糕数组发送到方法calcCostBenefit,因此方法中的任何更改都应反映外部的数组(调用方方法)。但实际上,这并没有发生。下面是输出:Value Cake cost benefit 1: 22.857143Value Cake cost benefit 1: 30Value Cake cost benefit 1: 7.5Value Cake cost benefit 2: 0Value Cake cost benefit 2: 0Value Cake cost benefit 2: 0 值重置为零,我不知道为什么。我尝试了代码中的一些更改,但没有任何效果。我在这里错过了什么?这让我发疯,没有任何东西能够发现可能如此明显和简单的东西。
查看完整描述

1 回答

?
森栏

TA贡献1810条经验 获得超5个赞

在提供的示例中,for 范围循环将基础项的值复制到一个新变量 () 中 — 随后在下面的示例中打印出来:slicearrayc


fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)

您可以使用 获取指向 中某个条目的指针。请注意 s 和 s 之间的区别,特别是当复制 s 时,基础保持不变:slicec := &cakes[i]slicearrayslicearray


...如前所述,重新切片不会创建基础数组的副本。整个数组将保留在内存中,直到不再被引用。有时,这可能会导致程序在只需要一小部分数据时将所有数据保存在内存中。...


https://blog.golang.org/slices-intro#TOC_6。


因此,如果只是尝试更改数组中的基础值(由 .sliceslice


所以,这个:


func maxDuffelBagValue(cakes []Cake, capacity int) int {


    calcCostBenefit(&cakes)


    for _, c := range cakes {

        fmt.Printf("Value Cake cost benefit 2: %v \n", c.costBenefit)

    }


    return 0

}


func calcCostBenefit(cakes *[]Cake) {

    for _, c := range *cakes {

        c.SetCostBenefit()

        fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)

    }

}


变成这样:


func maxDuffelBagValue(cakes []Cake, capacity int) int {

    calcCostBenefit(cakes)


    for _, c := range cakes {

        fmt.Printf("Value Cake cost benefit 2: %f \n", c.costBenefit)

    }


    return 0

}


func calcCostBenefit(cakes []Cake) {

    for i, _ := range cakes {

        c := &cakes[i]

        c.SetCostBenefit()

        fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)

    }

}

输出:


Value Cake cost benefit 1: 22.857143 

Value Cake cost benefit 1: 30 

Value Cake cost benefit 1: 7.5 

Value Cake cost benefit 2: 22.857143 

Value Cake cost benefit 2: 30.000000 

Value Cake cost benefit 2: 7.500000 


以下方法也有效:


func calcCostBenefit(cakes *[]Cake) {

    for idx, _ := range *cakes {

    c := &(*cakes)[idx]

        c.SetCostBenefit()

        fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)

    }

}

...但鉴于上面的替代方案,它更复杂。但是,如果由于任何原因(外部包)无法更改方法签名,则可能需要执行此操作。


https://play.golang.org/p/7OVw_IH2B0l


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号