Разыменование индекса карты в Golang

Я учусь идти в настоящее время, и я сделал эту простую и грубую программу инвентаризации просто возиться со структурами и методами, чтобы понять, как они работают. В файле драйвера я пытаюсь вызвать метод и тип элемента из карты элементов типа кассира. Мой метод имеет указатель reciever для использования структур непосредственно вместо создания копий. Когда я запускаю программу, я получаю эту ошибку .driver.go:11: cannot call pointer method on f[0] .driver.go:11: cannot take the address of f[0]

инвентаризации.go:

package inventory


type item struct{
    itemName string
    amount int
}

type Cashier struct{
    items map[int]item
    cash int
}

func (c *Cashier) Buy(itemNum int){
    item, pass := c.items[itemNum]

    if pass{
        if item.amount == 1{
            delete(c.items, itemNum)
        } else{
            item.amount--
            c.items[itemNum] = item 
        }
        c.cash++
    }
}


func (c *Cashier) AddItem(name string, amount int){
    if c.items == nil{
        c.items = make(map[int]item)
    }
    temp := item{name, amount}
    index := len(c.items)
    c.items[index] = temp
}

func (c *Cashier) GetItems() map[int]item{
    return c.items;
}

func (i *item) GetName() string{
    return i.itemName
}

func (i *item) GetAmount() int{
    return i.amount
}

драйвер.go:

package main

import "fmt"
import "inventory"

func main() {
    x := inventory.Cashier{}
    x.AddItem("item1", 13)
    f := x.GetItems()

    fmt.Println(f[0].GetAmount())
}

часть кода, который действительно относится к моей проблеме это на inventory.go и напечатать заявление в driver.go

3 ответов


запись карты не может быть адресована (поскольку ее адрес может измениться во время роста/сжатия карты), поэтому вы не можете вызывать методы приемника указателя на них.

подробно здесь:https://groups.google.com/forum/?fromgroups=#!тема/голанг-орехи/4_pabWnsMp0


Как сказал Волкер в своем ответе - вы не можете получить адрес элемента в карте. Что вам нужно сделать-это хранить указатели на элементы на вашей карте, а не хранить значения элементов:

package main

import "fmt"

type item struct {
    itemName string
    amount   int
}

type Cashier struct {
    items map[int]*item
    cash  int
}

func (c *Cashier) Buy(itemNum int) {
    item, pass := c.items[itemNum]

    if pass {
        if item.amount == 1 {
            delete(c.items, itemNum)
        } else {
            item.amount--
        }
        c.cash++
    }
}

func (c *Cashier) AddItem(name string, amount int) {
    if c.items == nil {
        c.items = make(map[int]*item)
    }
    temp := &item{name, amount}
    index := len(c.items)
    c.items[index] = temp
}

func (c *Cashier) GetItems() map[int]*item {
    return c.items
}

func (i *item) GetName() string {
    return i.itemName
}

func (i *item) GetAmount() int {
    return i.amount
}

func main() {
    x := Cashier{}
    x.AddItem("item1", 13)
    f := x.GetItems()
    fmt.Println(f[0].GetAmount()) // 13
    x.Buy(0)
    f = x.GetItems()
    fmt.Println(f[0].GetAmount()) // 12
}

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


в то время как другие ответы полезны, я думаю, что в этом случае лучше всего просто сделать не мутирующие функции не подвести указатель:

func (i item) GetName() string{
    return i.itemName
}

func (i item) GetAmount() int{
    return i.amount
}