2016-01-03 51 views
1

我想学习scala并理解函数和方法之间的区别。如何从scala中的匿名函数中获取值?

这是非常简单的代码,我写 -

scala> class C (acc:Int) { 
     | val minc = (acc + 1) 
     | val func = {() => acc += 3 } 
     | } 

    scala> val c1 = new C(3) 
     c1: C = [email protected] 

    scala> c1.minc 
     res2: Int = 4 

    scala> c1.func 
     res3:() => Int = <function0> 

我理解的实例化对象C1调用函数func的该结果被存储为另一种表达RES3。

但是我想获取价值的匿名函数()= ACC +3即C级

内。如果我试图通过参数RES3表达斯卡拉抛出一个错误

scala> res3(4) 
    <console>:11: error: too many arguments for method apply:()Int in trait Function0 
    res3(4) 
     ^

如何从中获得价值?

PS - 我刚刚开始使用scala,不知道这是否完全可能?

回答

5

这是你的func定义:

val func = {() => acc += 3 } 

让我们来看看什么是func类型的REPL看看。

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func 
c1.func 
res29:() => Unit = <function0> 

用普通的英语,这意味着“func指的是一个不接受参数且不返回值的函数。 Unit表示该方法不返回任何内容。如果您来自Java,那么它与void类似,作为返回类型。 function0表示它接受0个参数。

接下来,让我们来看看示例中的失败呼叫。

scala> c1.func(4) 
c1.func(4) 
<console>:10: error: too many arguments for method apply:()Unit in trait Function0 
       c1.func(4) 
        ^

现在我们知道了func的方法签名,这个错误信息应该更有意义。我们知道func引用了一个不接受参数的函数,但在此调用中,您试图用一个整数参数来调用它。由于方法调用的参数太多,因此Scala会将此误报为错误。

我不完全确定你想通过传递4作为参数来做什么。我最好的猜测是你试图通过将3添加到acc然后将它返回给调用者来应用该函数来计算其结果。如果我是正确的,那么我们可以重新定义C就象这样:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func =() => { 
    acc += 3 
    acc 
} 

scala> val c1 = new C(3) 
val c1 = new C(3) 
c1: C = [email protected] 

scala> c1.func() 
c1.func() 
res44: Int = 6 

当我们调用c1.func(),没有传递参数,以便它能够正确定义的方法签名匹配。

另一种可能性是,您尝试参数化增量并在调用中将4传递给它。如果是这样,那么你可以这样做:

class C(var acc:Int) { 
    val minc = (acc + 1) 
    val func = (delta: Int) => { 
    acc += delta 
    acc 
    } 
} 

scala> c1.func(4) 
c1.func(4) 
res45: Int = 7 

在这种情况下,我们已经声明匿名函数接受Int 1个型参数,所以当我们在方法调用传递4,它正确的方法签名匹配。

0

您并未以您想的方式声明匿名函数。这条线:

val func = {() => acc += 3 } 

这实际上宣告匿名函数。括号是第一个匿名函数(不带参数),() => acc += 3是第二个函数。通过使用括号,Scala允许您声明一个0元的匿名函数。如果你放弃这些,你会得到你想要的:

val func =() => acc += 3 

作为一个附注,你可以在类型签名中看到这一点。您当前的func签名是:

() => Int = <function0> 

这是一个函数,0参数,并返回一个整数。这不是你想要的。当你把它改变什么,我给你,你会得到这样的:

Int => Int = <function1> 

现在func接受一个参数,并且整数,并返回另一个整数,这是你想要的。

+0

谢谢你的解释!但是,当我尝试从功能中获得价值时,我仍然看到错误。 类别c(ACC:智力){ VAL MINC =(ACC + 1) VAL FUNC =()=> ACC + 3 } VAL C1 =新C(5) c1.minc打印6 但是,c1.func打印res23:()=> Int = 我期待输出8出这个对象。有没有其他方法可以用来从func中获取价值? – GoldenPlatinum