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
", c.costBenefit)
You can obtain a pointer to an entry in the slice
by using c := &cakes[i]
. Note the difference between slice
s and array
s, particularly that when slice
s 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 isn’t a 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
", c.costBenefit)
}
return 0
}
func calcCostBenefit(cakes *[]Cake) {
for _, c := range *cakes {
c.SetCostBenefit()
fmt.Printf("Value Cake cost benefit 1: %v
", 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
", 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
", 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
", 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