Go не может указать тип присваивания: "non-name на левой стороне: ="

Этот фрагмент работает как ожидалось play.golang.org/p/VuCl-OKMav

i := 10
next := 11
prev, i := i, next

Однако этот почти идентичный фрагмент дает non-name f.Bar on left side of := play.golang.org/p/J8NNWPugQG

type Foo struct {
    Bar int
}

f := Foo{10}
next := 11
prev, f.Bar := f.Bar, next

Что особенного в структуре, которая останавливает вывод типа? Это ошибка?

Ответы

Ответ 1

Это не проблема вывода типа, это просто, что левая сторона := должна быть списком идентификаторов, а f.Bar не является идентификатором, поэтому его нельзя объявить — даже с := несколько более разрешительными правилами для того, что он может объявить. См. "Короткие объявления переменных" в Спецификации языка программирования Go Go.

Ответ 2

Это открытая проблема.

Проблема 6842: spec: Назначение поля с короткой декларацией объявления

Ответ 3

Из раздела спецификаций "Short variable declarations":

"В отличие от обычных объявлений переменных, краткое объявление переменной может обновлять переменные, если они были изначально объявлены ранее в том же блоке... с тем же типом, и по крайней мере одна из непустых переменных является новой."

Итак, если вы объявляете переменную внутри другого типа (struct Foo в примере), она дисквалифицируется "при условии, что они были первоначально объявлены ранее в том же блоке".

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

...
var prev int
prev, f.Bar = f.Bar, next
...