Sobes.tech
Junior — Senior
48

Проблема вызова метода у значения, полученного из map

Компании, где спрашивали:

Notix Games
Условие задачи

В примере пытаются вызвать метод Fizz() у элемента, полученного из map, но компилятор выдаёт ошибку.

Почему происходит ошибка

Метод Fizz объявлен с указательным получателем *Bar. При обращении к элементу карты m["bar"] возвращается значение типа Bar, а не указатель. Значения, полученные из map, не являются адресуемыми, поэтому компилятор не может автоматически взять их адрес и вызвать метод с указательным получателем.

Варианты исправления

  1. Хранить в карте указатели на Bar:
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. Сделать получатель метода значением (не указателем):
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. Скопировать значение в переменную, взять её адрес и вызвать метод:
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()
}

Исходный код, вызывающий ошибку

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()
}