Pointer value set to zero after being changed in a struct method

iapolinario

Here is my code:

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)
    }
}

As you can see above, I have a struct method that sets the CostBenefit property of the struct Cake. As I'm sending the array of cakes to the method calcCostBenefit, any change within the method should reflect the array in the outside (caller method). But actually, it doesn't happen. Here's the output:

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: 0
Value Cake cost benefit 2: 0
Value Cake cost benefit 2: 0 

The values get reset to zero and I don't know why. I've tried several changes in the code, but nothing worked. What am I missing here? It's driving me crazy nothing being able to spot something that might be so obvious and simple.

xandercoded

In the provided example, the for range loop copies the value(s) of the underlying slice's array item into a new variable (c) — which is subsequently printed out in your example at:

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

You can obtain a pointer to an entry in the slice by using c := &cakes[i]. Note the difference between slices and arrays, particularly that when slices are copied, the underlying array remains the same:

... As mentioned earlier, re-slicing a slice doesn't make a copy of the underlying array. The full array will be kept in memory until it is no longer referenced. Occasionally this can cause the program to hold all the data in memory when only a small piece of it is needed. ...

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

Thus, there's need to pass the slice by reference if you're only attempting to change the underlying values in the array, referenced by the slice.

So, this:

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)
    }
}

Becomes this:

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)
    }
}

Output:

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 

NB

The following also works:

func calcCostBenefit(cakes *[]Cake) {
    for idx, _ := range *cakes {
    c := &(*cakes)[idx]
        c.SetCostBenefit()
        fmt.Printf("Value Cake cost benefit 1: %v \n", c.costBenefit)
    }
}

... but it's more complicated given the alternative above. Nevertheless, this may be required if you're not able to change method signatures for whatever reason (external packages).

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Set the value of a pointer in a struct

From Dev

Why does the z-index value remain unchanged, after being changed with the .css() method?

From Dev

Why does the z-index value remain unchanged, after being changed with the .css() method?

From Dev

what is the value after declaring a pointer to a struct

From Dev

value of asp:textbox is not being changed after written over it

From Dev

value of asp:textbox is not being changed after written over it

From Dev

Java Enum data long value being set to zero

From Dev

C pointer does not get set after being passed to a function

From Dev

cgo pointer value changed

From Dev

Go: How to check if a struct property was explicitly set to a zero value?

From Dev

Initialize members of a struct to zero via the struct pointer

From Dev

Breeze.Sharp nullable int , when set to zero on client, is being changed back to null on SaveChanges()

From Dev

Value of pointer inside an struct

From Dev

Boolean value not being changed in database

From Dev

Are there zero bytes after a `char` in a struct?

From Dev

variable becomes nil in numberOfRowsInTableView after being set in another method

From Dev

Initialize a nil pointer struct in method

From Dev

Struct's Zero value in golang

From Dev

Not able to obtain struct after passing in struct pointer

From Dev

Return pointer value changes after passing out from a method

From Dev

How do I prevent a pre-set INPUT value from being changed?

From Dev

How does ValidateSet stop a variable being changed to a non-set value?

From Dev

SQL Value being changed to 1 and not the value given

From Dev

Update pointer value in struct automatically

From Dev

Update pointer value in struct automatically

From Dev

Python local variable being changed by another method

From Dev

Inputs Remain Invalid After Being Changed by Javascript

From Dev

Set pointer to int value

From Dev

Set pointer to int value

Related Related

  1. 1

    Set the value of a pointer in a struct

  2. 2

    Why does the z-index value remain unchanged, after being changed with the .css() method?

  3. 3

    Why does the z-index value remain unchanged, after being changed with the .css() method?

  4. 4

    what is the value after declaring a pointer to a struct

  5. 5

    value of asp:textbox is not being changed after written over it

  6. 6

    value of asp:textbox is not being changed after written over it

  7. 7

    Java Enum data long value being set to zero

  8. 8

    C pointer does not get set after being passed to a function

  9. 9

    cgo pointer value changed

  10. 10

    Go: How to check if a struct property was explicitly set to a zero value?

  11. 11

    Initialize members of a struct to zero via the struct pointer

  12. 12

    Breeze.Sharp nullable int , when set to zero on client, is being changed back to null on SaveChanges()

  13. 13

    Value of pointer inside an struct

  14. 14

    Boolean value not being changed in database

  15. 15

    Are there zero bytes after a `char` in a struct?

  16. 16

    variable becomes nil in numberOfRowsInTableView after being set in another method

  17. 17

    Initialize a nil pointer struct in method

  18. 18

    Struct's Zero value in golang

  19. 19

    Not able to obtain struct after passing in struct pointer

  20. 20

    Return pointer value changes after passing out from a method

  21. 21

    How do I prevent a pre-set INPUT value from being changed?

  22. 22

    How does ValidateSet stop a variable being changed to a non-set value?

  23. 23

    SQL Value being changed to 1 and not the value given

  24. 24

    Update pointer value in struct automatically

  25. 25

    Update pointer value in struct automatically

  26. 26

    Python local variable being changed by another method

  27. 27

    Inputs Remain Invalid After Being Changed by Javascript

  28. 28

    Set pointer to int value

  29. 29

    Set pointer to int value

HotTag

Archive