Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Go Language Go Language Overview Data Structures Maps

I'm amazed that this doesn't work?

It seems that the operation here is valid, but modifying p doesn't modify the mapped values, but only a copy of the mapped values. In this case, I think it is passed by value.

I tried this locally with debugger and indeed it is changed but not saved to the maps.

package main

import "fmt"

func HalfPriceSale(prices map[string]float64) map[string]float64 {
    for _, p := range prices {
        p = p / 2
    }
    return prices
}

func main() {
    priceList := map[string]float64{"apple": 1.99, "grapes": 5.99, "milk": 0.99}
    fmt.Println(priceList)
    fmt.Println(HalfPriceSale(priceList))
}
src/sales/sales.go
package sales

func HalfPriceSale(prices map[string]float64) map[string]float64 {
    for _, p := range prices {
        p = p / 2
    }
    return prices
}

I'm also surprised that this is not valid Golang code, but it will absolutely work in C++

    priceList := map[string]float64 {
        "apple": 1.99,
        "grapes": 5.99,
        "milk": 0.99
    }

1 Answer

Hello

This behaviour is detailed on their website

If a function takes a slice argument, changes it makes to the elements of the slice will be visible to the caller, analogous to passing a pointer to the underlying array.

Maps and slices are reference types so your loop is referencing over an underlying data structure, this means that changing it like the above, wont change the referenced value.

Here is 2 examples:

type MapOfValus map[string]float64

func HalfPriceSale(prices MapOfValus) MapOfValus {
    halfPrice := MapOfValus{}
    for key, val := range prices {
        halfPrice[key] = val / 2
    }
    return halfPrice
}

func HalfPriceSale2(prices MapOfValus) MapOfValus {
    for key, val := range prices {
        prices[key] = val / 2
    }
    return prices
}