Sobes.tech
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

  1. Store pointers to Bar in 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()
}
  1. 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()
}
  1. 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()
}