2013-11-26 9 views
8

Ich lerne gerade Go und ich machte dieses einfache und grobe Inventar-Programm, nur um mit Strukturen und Methoden zu basteln, um zu verstehen, wie sie funktionieren. In der Treiberdatei versuche ich eine Methode von und einen Artikeltyp aus der Artikelliste des Kassetyps aufzurufen. Meine Methode verfügt über Zeigerempfänger, um die Strukturen direkt zu verwenden, anstatt Kopien zu erstellen. Wenn ich das Programm laufen bekomme ich diesen Fehler .\driver.go:11: cannot call pointer method on f[0] .\driver.go:11: cannot take the address of f[0]Dereferenzierung eines Kartenindex in Golang

Inventory.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 
} 

Driver.go:

package main 

import "fmt" 
import "inventory" 

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

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

Der Teil des Codes, der bezieht sich auf mein Problem ist wirklich die GetAmount Funktion in inventory.go und Druckanweisung im driver.go

Antwort

12

Wie Volker sagte in seiner Antwort - Sie nicht Adresse eines Postens in der Karte bekommen. Was Sie tun sollten - ist Zeiger auf Elemente in der Karte zu speichern, anstatt Itemwerte der Speicherung:

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

0

Während die anderen Antworten nützlich sind, denke ich, in diesem Fall ist es am besten, nur um machen Sie nicht-mutierende Funktionen nicht nehmen Sie einen Zeiger:

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

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