Golang: особенности видимости переменных

Задача: достать всех родителей категории, исключая текущую категорию.

func (s *Service) Parents(category *model.Category) ([]*model.Category, error) {
	var categories []*model.Category

	cur := category
	for cur.ParentID > 0 {
		cur, err := cur.Parent()
		if err != nil {
			return nil, err
		}

		categories = append(categories, cur)
	}

	// reverse the slice
	for i, j := 0, len(categories)-1; i < j; i, j = i+1, j-1 {
		categories[i], categories[j] = categories[j], categories[i]
	}
	return categories, nil
}

Код вроде простой (я выкинул из него всё, что не относится к делу), но в нём есть одна ошибка - он приводит к бесконечному циклу.
Проблема в том, что в строке cur, err := cur.Parent ради объявления на месте переменной err был использован оператор :=.
В итоге объявляется новая переменная cur, область видимости которой ограничена блоком for.
В принципе, ничего страшного в этом нет. Но дело в том, что в объявлении цикла for cur.ParentID > 0 используется первая переменная cur, и поэтому цикл никогда не прекратится.

LEAVE A COMMENT