1

Coming from C#, this puzzles me. In Go, if I have

type Employee struct {
   ID     int
   Salary int
}

then I can do

var tom Employee
tom.Salary = 100

so far so good. Then if I have a function

func employeeByID(id int) Employee {
   // do something and return an employee
}

Then why does this not compile?

employeeByID(10).Salary = 100

Moreover, this seems to compile fine:

andrew := employeeByID(10)
andrew.Salary = 100
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
dragonfly02
  • 3,403
  • 32
  • 55
  • 1
    What do you expect `employeeByID(10).Salary = 100` to do? It would make sense if the function returned `*Employee` instead. – bereal Jan 08 '21 at 09:11
  • 8
    For the same reason you can't do `5 = 10`. Why would you want to assign a value to something that itself is not stored anywhere? – super Jan 08 '21 at 09:14
  • 1
    You can't do it even in C# – meshkati Jan 08 '21 at 10:20

1 Answers1

14

It doesn't compile because that assignment is not valid.

Spec: Assignments:

Each left-hand side operand must be addressable, a map index expression, or (for = assignments only) the blank identifier.

The return values of function calls are not addressable. For details, see How to get the pointer of return value from function call? and How can I store reference to the result of an operation in Go?

Think about it: you call a function, it returns a value (which you don't store), what good would come from changing it if you don't store the result? It would be discarded, and so the assignment would also be useless.

If you store the result in a variable like in your second example, you can change its fields because variables are addressable.

icza
  • 389,944
  • 63
  • 907
  • 827