Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increment struct variable in go

Tags:

go

I was expecting to see 3, what's going on?

package main

import "fmt"

type Counter struct {
    count int
}

func (self Counter) currentValue() int {
    return self.count
}
func (self Counter) increment() {
    self.count++
}

func main() {
    counter := Counter{1}
    counter.increment()
    counter.increment()

    fmt.Printf("current value %d", counter.currentValue())
}

http://play.golang.org/p/r3csfrD53A

like image 270
OscarRyz Avatar asked May 17 '13 13:05

OscarRyz


2 Answers

Your method receiver is a struct value, which means the receiver gets a copy of the struct when invoked, therefore it's incrementing the copy and your original isn't updated.

To see the updates, put your method on a struct pointer instead.

func (self *Counter) increment() {
    self.count++
}

Now self is a pointer to your counter variable, and so it'll update its value.


http://play.golang.org/p/h5dJ3e5YBC

like image 97
user1106925 Avatar answered Sep 24 '22 07:09

user1106925


I want to add to @user1106925 response.

If you need to use the custom type inside a map you need to use a map to pointer. because the for l,v :=range yourMapType will receive a copy of the struct.

Here a sample:

package main

import "fmt"

type Counter struct {
        Count int
}

func (s *Counter) Increment() {
        s.Count++
}

func main() {
        // Using map to type
        m := map[string]Counter{
                "A": Counter{},
        }

        for _, v := range m {
                v.Increment()
        }
        fmt.Printf("A: %v\n", m["A"].Count)

        // Now using map to pointer
        mp := map[string]*Counter{
                "B": &Counter{},
        }

        for _, v := range mp {
                v.Increment()
        }
        fmt.Printf("B: %v\n", mp["B"].Count)
}

The output is:

$ go build && ./gotest
A: 0
B: 1
like image 39
ton Avatar answered Sep 25 '22 07:09

ton