deft_code
deft_code

Reputation: 59269

Go fails to infer type in assignment: "non-name on left side of :="

This snippet works as expected play.golang.org/p/VuCl-OKMav

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

However this nearly identical snippet gives 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

What's special about the struct that stops type inference? Is this a bug?

Upvotes: 42

Views: 49911

Answers (4)

YassBan
YassBan

Reputation: 91

it is just that you already assigned f to Foo f := Foo{100} in this case f.Bar is 100 so to reassign it just remove the column

var prev string
f := Foo{10}
next := 11
prev, f.Bar = f.Bar, next
this will work

Upvotes: 0

peterSO
peterSO

Reputation: 166569

It's an open issue.

Issue 6842: spec: Assigning to fields with short declaration notation

Upvotes: 27

Sean Williams
Sean Williams

Reputation: 166

From the spec's Short variable declarations section:

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block...with the same type, and at least one of the non-blank variables is new.

So if you declare the variable inside another type (struct Foo in the example), it is disqualified by "provided they were originally declared earlier in the same block".

So the answer is to just set the pre-declared variable equal not using the := syntax to the value:

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

Upvotes: 15

ruakh
ruakh

Reputation: 183271

It's not really a type inference issue, it's just that the left-hand-side of := must be a list of identifiers, and f.Bar is not an identifier, so it can't be declared — not even with :='s slightly-more-permissive rules for what it can declare. See "Short variable declarations" in The Go Programming Language Specification.

Upvotes: 22

Related Questions