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

huangapple go评论76阅读模式
英文:

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

问题

我来自Scala背景,在Scala中,你可以将函数定义为单个值或实际函数,例如:

val inc1: Int => Int = _ + 1 // 单个函数值
def inc2(x: Int): Int = x + 1 // 普通函数定义
// 在这种情况下,"inc1 eq inc1"为true,因为这是一个单个实例
// 但"inc2 eq inc2"为false

这两种方式有一些区别(例如,大小分配,第一种方式是单个实例,而第二种方式在每次调用时返回一个实例...),因此根据使用情况,我们可以推断出使用哪种方式。现在我对Go语言还不熟悉,想知道下面这两种函数定义(如果我用的短语不正确,请纠正)在Go语言中是否有区别,如果有,有什么区别?

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

提前感谢!

英文:

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!

答案1

得分: 5

Scala从函数式编程中借鉴了很多东西,而Go没有。

(如果你使用过其他多种编程语言,你应该阅读Go规范。它并不长,因为Go并不是一种非常庞大的语言,尽管新的泛型确实使事情变得有点复杂。)

在Go中,func关键字引入了一个函数定义或函数类型,具体细节取决于上下文。var关键字引入了一个变量声明。所以:

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

定义了一个名为inc2的函数,其代码如上所示。但是:

var inc1 = // ...

声明并初始化了一个变量inc1。变量的类型和初始由注释部分确定,所以:

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

定义了一个没有名字的函数,其代码如上所示。然后,将该函数赋值给变量作为其初始值,因此变量的隐含类型func (int) int,即接受一个类型为int的参数并返回一个类型为int的值的函数。

创建了一个变量后,现在可以调用当前存储在该变量中的函数:

func callit(arg int) {
    result := inc1(arg)
    // ... 对结果进行操作 ...
}

或者可以将新值赋给变量,例如:

func overwrite() {
    inc1 = func(a int) int { return a * 2 } // 现在`inc1`的名称有些误导性
}

因为inc2是一个函数,所以不能为其重新赋值:它只是一个函数,不是一个变量。


注意:带有初始化的变量声明可以使用“短声明”形式:

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

在这里,我们省略了类型,并且只是说“使用表达式的类型来确定声明的类型”。这样声明并初始化了变量。短声明只能出现在块作用域中,所以它们必须在某个函数内部。除了省略var关键字外,它们并没有做任何你不能通过包含var关键字或有时使用多个var关键字来做的事情:

result, err := doit()

可能需要:

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

当不使用短声明形式编写时。

英文:

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.<sup>1</sup> 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.


<sup>1</sup>Note 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.

huangapple
  • 本文由 发表于 2022年5月8日 17:12:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/72159559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定