Junior — Senior
Calling method on a value obtained from a map
livecode
Task condition
The example attempts to call the Fizz() method on an element obtained from a map, but the compiler reports an error.
Why does the error occur
The Fizz method is declared with a pointer receiver *Bar. When accessing the map element m["bar"], it returns a value of type Bar, not a pointer. Values retrieved from a map are not addressable, so the compiler cannot automatically take their address to call a method with a pointer receiver.
Ways to fix
- Store pointers to
Barin the map:
package main
import "fmt"
type Bar struct{}
func (b *Bar) Fizz() {
fmt.Println("buzz")
}
func main() {
m := map[string]*Bar{"bar": &Bar{}}
m["bar"].Fizz()
}
- Make the receiver a value (not a pointer):
package main
import "fmt"
type Bar struct{}
func (b Bar) Fizz() {
fmt.Println("buzz")
}
func main() {
m := map[string]Bar{"bar": Bar{}}
m["bar"].Fizz()
}
- Copy the value into a variable, take its address, and call the method:
package main
import "fmt"
type Bar struct{}
func (b *Bar) Fizz() {
fmt.Println("buzz")
}
func main() {
m := map[string]Bar{"bar": Bar{}}
v := m["bar"]
(&v).Fizz()
}
Original code that causes the error
package main
import "fmt"
type Bar struct{}
func (b*Bar)Fizz(){
fmt.Println("buzz")
}
func main() {
m :=map[string]Bar{"bar": Bar{}}
m["bar"].Fizz()
}