分配给nil映射中的条目,初始化映射没有

The code below gives me "assignement to entry in nil map" error, I searched this error, and many answer says I need to initialize my map, I tried to initialize the map need as "need := make(map[string]Item)" it still gives me the same error, b.ingredients returns a type of map[string]Item, what is my mistake here ?

func (b *Bread) ShoppingList(have map[string]Item) (difference map[string]Item, left map[string]Item) {

    need := b.ingredients

    for k, v := range need {
        flag := false
        for key, value := range have {
            if key == k {
                flag = true
                if value.weight > v.weight {
                    left[key] = Item{value.weight - v.weight}
                } else {
                    difference[key] = Item{v.weight - value.weight}
                    left[key] = Item{0}
                }
                break
            }
        }
        if !flag {
            need[k] = v
        }
    }

    return
}

type Bread struct {
    name        string
    ingredients map[string]Item
    weight      float32
    Baking
}

type Item struct {
    weight int
}
func main() {
have := map[string]Item{"Whole wheat flour": Item{5000}, "sugar": Item{1000}, "salt": {500}}

tmp := map[string]Item{"white flour": Item{200}, "sesame": Item{50}}
tmp2 := map[string]Item{"Whole wheat flour": Item{250}}
slices := [...]Baker{NewBread(), NewBreadVariation("Sesame bread", tmp, tmp2)}
slices[0].PrintBreadInfo()
slices[1].PrintBreadInfo()
difference, left := slices[0].ShoppingList(have)
//differencce1, _ := slices[1].ShoppingList(left)

fmt.Print(difference)
fmt.Print(left)
fmt.Print(have)
//fmt.Print(differencce1)
}


type Baker interface {
ShoppingList(map[string]Item) (map[string]Item, map[string]Item)
PrintBakeInstructions()
PrintBreadInfo()
}

func NewBread() (brd *Bread) {

ing := map[string]Item{"Whole wheat flour": Item{500}, "yeast": Item{25}, "salt": Item{25},
    "sugar": Item{50}, "butter": Item{50}, "water": Item{350}}
bk := Baking{120, 60, 180}
brd = &Bread{"Whole wheat", ing, 1.000, bk}
return
}

func NewBreadVariation(name string, add map[string]Item, removed map[string]Item) (brd *Bread) {
var weight float32
bk := Baking{120, 60, 180}
origin := map[string]Item{"Whole wheat flour": Item{500}, "yeast": Item{25}, "salt": Item{25},
    "sugar": Item{50}, "butter": Item{50}, "water": Item{350}}

if add != nil {
    for k, v := range add {
        flag := false
        for key, value := range origin {

            if key == k {
                flag = true
                origin[key] = Item{v.weight + value.weight}
                break
            }

        }

        if !flag {
            origin[k] = v
        }

    }
}
if removed != nil {
    for k, v := range removed {
        flag2 := false
        for key, value := range origin {
            if k == key {
                flag2 = true
                origin[key] = Item{value.weight - v.weight}
                break
            }
        }

        if !flag2 {
            fmt.Print("something wrong")
        }

    }
}

for _, v := range origin {
    tmp := v.weight
    tmp2 := float32(tmp)
    weight += tmp2
}
weight2 := weight / 1000

return &Bread{name, origin, weight2, bk}
}

You are using named return values in your ShoppingList function, so difference and left are declared: they are set to the types' zero-values. For maps, this is nil (see spec) - naturally, appending an item to a nil map results in a panic.

So, before appending any items to them, do the following to assign them a value:

difference = make(map[string]Item)
left = make(map[string]Item)