函数文字 - 需要帮助理解代码片段

时间:2012-09-21 19:26:14

标签: scala

我基本上不熟悉函数式编程和scala,以下问题可能看起来很愚蠢。

val f = (a:Int) => a+1

在上面的代码片段中,我应该将f视为函数还是变量?来自C / C ++背景,首先想到的是f是一个存储匿名函数返回值的变量,但我认为这不是解释它的正确方法任何解释都会有所帮助

(我在上面使用的一些术语在scala /函数式编程方面可能是错误的,请小心使用它)

3 个答案:

答案 0 :(得分:5)

这里,f是存储函数的变量。这与以下任何一项都没有什么不同:

val a = 4               // `a` is a variable storing an Int
val b = "hi"            // `b` is a variable storing a String
val f = (a:Int) => a+1  // `f` is a variable storing a function

您也可以使用REPL确认:

scala> val f = (a:Int) => a+1
f: Int => Int = <function1>

因此,这告诉您f的类型为Int => Int。或者换句话说,f是一个函数,它接受一个参数Int,并返回Int

由于f是一个变量,您可以在其上调用方法或将其作为参数传递给期望其类型的函数:

a + 3  // here I'm calling the `+` method on `a`, which is an Int
f(3)   // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a)   // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f)  // the `map` method expects a function from Int to Int, like `f`

答案 1 :(得分:1)

是的,就像dhg所说,f是一个存储函数的变量(无法更改)。

然而,这里有一个微妙的地方:

  

......首先想到的是f是一个存储的变量   匿名函数的返回值

f实际上存储了函数,而不是结果。因此,您可以为其提供不同的输入,并获得不同的输出。因此,您可以使用f(7),然后f(5)。 Scala中的函数是对象,因此可以分配给变量,作为参数传递等。

I recently posted about function literals,这可能会对您有所帮助。

答案 2 :(得分:0)

f是一个值,表示函数文字。

在声明中,右侧是函数文字。左侧将其绑定到名称,然后将其命名为val关键字与LISP中的let类似)。现在该函数与符号f相关联,因此您可以使用此符号f来引用该函数。

我不同意其他答案,这些答案表明f应该被称为变量。 f是一个值,因为它固定在右侧的术语中,该术语仅确定无法更改。相反,使用var引入的变量允许您为符号重新赋值:

var f = (i: Int) => i + 1

var开始变量定义,f是变量的名称或符号,可以有一个可选的: ...定义变量类型(如果你把它留下来,从分配中自动推断出类型),= ...定义分配给变量的最初值。

因此,当一个人说 value 时,不要将其与数字常量混淆,它只是一个实体,不会改变。函数也可以是一个值,因为f总是表示同一个相同的函数,即使你可以用不同的参数提供该函数产生不同的结果。

现在使用var,您可以重新分配其右侧:

f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4

功能编程就是避免变量(重新分配)。


也可以定义一个函数而根本不分配它(对一个值或一个变量)。以下定义了这样一个函数,并立即使用参数4

调用它
{ i: Int => i + 1 } apply 4 // --> 5

虽然这本身很少用作语句,但是在调用需要函数参数的方法时,你会经常看到“普通”函数。例如

val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 }             // equivalent
s.map( _ + 1 )              // equivalent