0

I have a simple struct and receiver. I try to set the map with the struct and then call the receiver.

Like that:

package main

import (
    "fmt"
)

type myStruct struct {
    FirstName string 
    LastName string
}

func (m *myStruct) GetFirstName() string {
    return m.FirstName
}

func (m *myStruct) GetLastName() string {
    return m.LastName
}


func main() {
    


    testMyStruct := myStruct {
        FirstName: "x1",
        LastName: "x2",
    }

    myMapStruct["test2"] = testMyStruct 

     

    fmt.Println(myMapStruct["test2"].GetFirstName())


}

I'm getting this error:

 cannot call pointer method getFirstName on myStruct

Why can I call the receiver method from the map?

1
  • 1
    The expression x.M(), where x is of type T and M is a method of *T, is shorthand for (&x).M(). However, for (&x).M() to be valid x MUST be addressable. A map index expression, e.g. m[k], is NOT addressable. Therefore m[k].M() is illegal if m[k] is of type T and M is a method of *T. One of the reasons why m[k] is not addressable is that "growing a map might cause rehashing of existing elements into new storage location, thus potentially invalidating the address" (from The Go Programming Language book). Commented Jun 24, 2022 at 7:27

1 Answer 1

3

As you are passing a receiver pointer ,you have to use pointer to the struct to call it ,Please look at the below code

package main

import (
    "fmt"
)

type myStruct struct {
    FirstName string 
    LastName string
}

func (m *myStruct) GetFirstName() string {
    return m.FirstName
}

func (m *myStruct) GetLastName() string {
    return m.LastName
}


func main() {
    


    testMyStruct := &myStruct {
        FirstName: "x1",
        LastName: "x2",
    }

  myMapStruct:=make(map[string]*myStruct)

    myMapStruct["test2"] = testMyStruct 

     

    fmt.Println(myMapStruct["test2"].GetFirstName())



}

See working here

or You can use like below if passing receiver as value

package main

import (
    "fmt"
)

type myStruct struct {
    FirstName string 
    LastName string
}

func (m myStruct) GetFirstName() string {
    return m.FirstName
}

func (m myStruct) GetLastName() string {
    return m.LastName
}


func main() {
    


    testMyStruct := myStruct {
        FirstName: "x1",
        LastName: "x2",
    }

  myMapStruct:=make(map[string]myStruct)

    myMapStruct["test2"] = testMyStruct 

     

    fmt.Println(myMapStruct["test2"].GetFirstName())



}
Sign up to request clarification or add additional context in comments.

2 Comments

what is the best practice if i dont want to copy values , the first example ? what is uselly used in go code?
receiver pointer is a better approach ,but if you dont have large structs then value reeciver is also fine

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.