I don't know what you mean about "many ways to declare... a function." Unless you mean the fact that you can elide repeated types ("func foo(a int, b int)" vs "func foo(a, b int)"), which is just simple sugar to stop repeating yourself; or maybe you're referring to the named result parameters. Both of these are conveniences, and I wouldn't really say that they are different "ways" (syntactic constructs) to do something.
Variables in Go can be a bit tricky, but it's really not too difficult. In functions, declaring a variable with "var" requires a type and optionally and initializer. The ":=" construct declares and initializes a new variable whose type is inferred to be that of the righthand expression. Again it's just a convenience so you can stop repeating yourself.
The problem with having three ways of declaring a variable I think is that you either have to ask yourself each time which is the best way to do it or just have a mental order of which one is the most efficient and take the most efficient one that you can. I would just assume that being explicit about the type is the most efficient way. Is it?
If you don't declare a type, it has to be infered from the argument, which happens at compile time, so there's really no loss in performance. If Go would use some kind of union/variant type in those cases, then yes, that would cost you performance. But something like this is rather common in contemporary statically compiled languages, as nobody wants to uselessly repeat himself (cf. Java's "FrobnicationType frobnicatorVariable = new FrobnicatorType(initialValue)").
It's mostly a matter of style and verbosity, the only thing you have to care about is that you can't use the ":=" outside of functions. And as that will give you compilation errors, you'll notice quickly. No different behavior or runtime faults.
> The problem with having three ways of declaring a variable
Three ways? I only count two, and the rule for what to use is very simple: any time the type can be inferred from the initial value, you use := (obviously you can't use := in other cases, so there isn't really any ambiguity).
Variables in Go can be a bit tricky, but it's really not too difficult. In functions, declaring a variable with "var" requires a type and optionally and initializer. The ":=" construct declares and initializes a new variable whose type is inferred to be that of the righthand expression. Again it's just a convenience so you can stop repeating yourself.