присвоение записи в карте nil, карта инициализации не

avatar
YuanZheng Hu
8 апреля 2018 в 07:26
842
1
-2

Приведенный ниже код дает мне ошибку «назначение записи в нулевой карте», я искал эту ошибку, и во многих ответах говорится, что мне нужно инициализировать мою карту, я попытался инициализировать карту нужно как «need := make(map[ string]Item)" все равно выдает ту же ошибку, b.ingredients возвращает тип map[string]Item, в чем здесь моя ошибка?

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}
}
Источник
Himanshu
8 апреля 2018 в 07:28
0

Пожалуйста, опубликуйте структуру карты Bread. Непонятно что такое b.ingredients

YuanZheng Hu
8 апреля 2018 в 07:45
0

@Himanshu Я разместил это, спасибо, что заметили

Emile Pels
8 апреля 2018 в 07:46
0

@YuanZhengHu Пожалуйста, также опубликуйте, как вы инициализируете Bread (и конкретно это поле ingredients).

mh-cbon
8 апреля 2018 в 07:58
0

недостаточно подробностей

Himanshu
8 апреля 2018 в 08:00
0

Что осталось, что вы используете, а также в какой строке вы получаете здесь, укажите комментарий в коде, где вы получаете ошибку

Ответы (1)

avatar
Emile Pels
8 апреля 2018 в 08:08
1

Вы используете именованные возвращаемые значения в своей функции ShoppingList, поэтому difference и left являются объявленными: им присваиваются нулевые значения типов. Для карт это nil (см. спецификацию) — естественно, добавление элемента к карте nil приводит к панике.

Итак, прежде чем добавлять к ним какие-либо элементы, сделайте следующее, чтобы присвоить им значение:

difference = make(map[string]Item)
left = make(map[string]Item)
YuanZheng Hu
8 апреля 2018 в 08:25
0

Спасибо! Есть ли разница между инициализацией карты с помощью make и назначением переменной карты с помощью ":=" ? Я новичок в Go

Peter
8 апреля 2018 в 09:36
1

@YuanZhengHu, я настоятельно рекомендую вам принять участие в туре. Это описано в разделе «Краткие объявления переменных».

Emile Pels
8 апреля 2018 в 16:33
0

@YuanZhengHu Обратите внимание, что здесь следует использовать = вместо :=. Если вы отправитесь в тур, как предлагает Питер, вы поймете, почему :)