Fionser
Fionser

Reputation: 171

The argument in golang RPC call

In the RPC handler function, I omit the first argument like:

func (self Handler) GetName(int, reply *StructObj) {
}

and in the calling side

var reply StructObj
client.Call("Handler.GetName", 0, &reply)

Because I do not need the first argument in the GetName Method, I omit its name, HOWEVER, I got:

gob: type mismatch in decoder: want struct type

I changed the GetName method to GetName(id int, reply *StructObj) and it works. I want to know why this happened?

Upvotes: 5

Views: 3345

Answers (1)

twotwotwo
twotwotwo

Reputation: 30067

You hit a tricky aspect of function definition syntax in Go. You can't have an unnamed argument, and you can name an argument int, and func f(x, y, z Type) is a shortcut to declare all three variables to be of type Type. For example, func f(int, x string) counterintuitively declares an f that accepts two strings, one of which happens to be named int.

package main

import "fmt"

func f(int, x string) {
    fmt.Println("int is:", int)
    fmt.Println("x is:", x)
}

func main() {
    f("foo", "bar")
}

When you run it, the output is

int is: foo
x is: bar

Yes, that's a little mind-bending. I've never heard the specific thinking explained, but maybe they kept builtin type names un-reserved so they could later introduce new builtin types without breaking code that's already out there.

Anyway, it means your first function definition doesn't actually accept an int and a *StructObj but a *StructObj named int and another named reply. So the error message from net/rpc actually means that the client passed a 0 when it expected a *StructObj. Pretty fun.

Upvotes: 7

Related Questions