Go – The difference between var and func to define a function

Issue

I’m coming from an Scala background, and in Scala, you could define functions both as a single value, or an actual function, for instance:

val inc1: Int => Int = _ + 1 // single FUNCTION value
def inc2(x: Int): Int = x + 1 // normal function definition
// in this case "inc1 eq inc1" is true, since this is a single instance
// but "inc2 eq inc2" is false

And these 2 have some differences (i.e., size allocation, first one is a single instance, while the other one returns an instance each time it is invoked, …), so based on the use case, we could kind of reason which one to use. Now I’m new to golang, and wanted to know if the below 2 function definitions (correct me if I’m wrong with the phrase) differ in Golang, and if so, what are differences?

var inc1 = func(x int) int { return x + 1 }
func inc2(x int) int { return x + 1 }

Thanks in advance!

Solution

Scala borrows a lot from functional programming. Go does not.

(If you’ve used multiple other programming languages, you should definitely read the Go specification. It’s not very long as Go is not a very large language, although the new generics definitely complicate things a bit.)

In Go, the func keyword introduces a function definition or function type, with the details being context-dependent. The var keyword introduces a variable declaration.1 So:

func inc2(x int) int { return x + 1 }

defines a function, inc2, whose code is as shown. But:

var inc1 = // ...

declares and then initializes a variable, inc1. The type and initial value of the variable are determined by the commented-out section, so:

var inc1 = func(x int) int { return x + 1 }

defines a function (with no name) whose code is as shown. That function is then assigned to the variable as its initial value, so that the implied type of the variable is func (int) int or function taking one argument of type int and returning one value of type int.

Having created a variable, you can now either call the function currently stored in that variable:

func callit(arg int) {
    result := inc1(arg)
    // ... do something with the result ...
}

Or you can assign a new value into the variable, e.g.:

func overwrite() {
    inc1 = func(a int) int { return a * 2 } // name `inc1` is now misleading
}

Because inc2 is a function, you can’t re-assign a new value to it: it’s just a function, not a variable.


1Note that a variable declaration with an initialization can use the "short declaration" form:

func f() {
    v := 3
    // ...
 }

where we leave out the type and just say "use the type of the expression to figure out the type of the declaration". This declares and initializes the variable. Short declarations can only appear in block scope, so these must be inside some function. Other than omitting the var keyword they do nothing that you couldn’t do by including the var keyword, or sometimes multiple var keywords:

    result, err := doit()

might require:

    var result someType
    var err error
    result, err = doit()

when written without using the short-declaration form.

Answered By – torek

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.