指针映射与使用映射的常用方式不同

I want to create cache with map. As map doesn't allow reference to its value, so it's not possible to change values in called functions.

After some search, I found, it's possible with creating map of pointer (of struct). It Almost solve problem and can work like variable by reference But as i found a few using of this method for map. I worry about using it to be safe. Is anyone has experience of using map of pointer? and is it right way to use it?

package main

import "fmt"

type Cache struct {
    name    string
    counter int
}

func incr(c Cache) {
    c.counter += 1
}
func incrp(c *Cache) {
    c.counter += 2
}

func main() {
    m := make(map[string]Cache)
    m["james"] = Cache{name: "James", counter: 10}

    c := m["james"]
    incr(c)
    fmt.Println(c.name, c.counter) // James 10

    mp := make(map[string]*Cache)
    mp["james"] = &Cache{name: "James", counter: 10}
    cp := mp["james"]
    incrp(cp)
    fmt.Println(cp.name, cp.counter) // James 12

}

edited: My text had some confusing words and sentences, that caused to misunderstanding, so i tried to fixed it

You can accomplish this and still have a map of non-pointers, with a pointer receiver on the struct:

package main

import "fmt"

type Cache struct {
    name    string
    counter int
}

func (c *Cache) incr() {    // the '(c *Cache)' is the receiver;
    c.counter += 1          // it makes incr() a method, not just a function
}

func main() {
    m := make(map[string]Cache)
    m["james"] = Cache{name: "James", counter: 10}

    c := m["james"]
    c.incr()
    fmt.Println(c.name, c.counter)
}

Output:

James 11

If receivers and methods are new to you, here is where they are mentioned in the Tour of Go: https://tour.golang.org/methods/1

Note the page about pointer receivers a few steps later in the Tour: https://tour.golang.org/methods/4