Разыменование индекса карты в 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
}
в то время как другие ответы полезны, я думаю, что в этом случае лучше всего просто сделать не мутирующие функции не подвести указатель:
func (i item) GetName() string{
return i.itemName
}
func (i item) GetAmount() int{
return i.amount
}