2017-09-06 80 views
4

我正在使用Scala 2.11。如果我创建像一个函数:VarArgs A * vs Seq [A]参数到函数

def func1 (a: Int*) : Int = a.reduce(_+_) 

我把它用

func1(1,2,3,4) 
// 10 
func1(Seq(1,2,3,4) : _*) 
//10 

这是罚款。

但当我尝试定义函数文本,如:

val func2:(Int*) => Int = _.reduce(_+_) 

我得到一个错误说:

<console>:5: error: type mismatch; 
found : Int* => Int 
required: Seq[Int] => Int 
    lazy val $result = INSTANCE.`func2` 

为什么它要在第二种情况下Seq[Int]但不是在第一,虽然定义是一样的吗?

在第一种情况下如何传递可变参数以使reduce可以通过它们被调用?

+1

可能重复的[Scala中的函数对象的可变参数?](https://stackoverflow.com/questions/8623126/error-with-varargs-for-function-objects-in-scala) – Suma

回答

2

斯卡拉区分方法和函数。您的func1是一种方法,其参数为repeated,并且这个方法在简单的Seq之下被解密。另一方面,您的func2是一个函数,并且在该上下文中不允许重复的参数。

如果编译器需要一个函数,但是会给出一个方法,它会执行eta-expansion。例如,方法def(s: String) = s变成函数(s: String) => s。我这样说是为了表明方法和功能之间的区别非常明确和非常重要。

请注意,我提供的链接表示“函数声明和定义”,这是一种笨拙的命名,因为它实际上是在谈论方法而不是函数。功能与任何其他功能都是一样的,它可以是保存在一个集合中或从另一个函数返回。方法不能。

一个最后的评论和我完成了:不要犯一个常见的错误,并认为“def是方法,val是函数”。功能也可以使用def而不是val定义,在这种情况下,它仍然是一个函数值,但是它在使用点而不是声明点进行评估。区分方法和功能的最佳方法是检查参数:def foo(someParameter: X): Y是一种方法。函数不能有“(someParameter:X)”部分。相反,功能仅仅是一个值,其是X => Y:

// method 
def foo(x: X): Y = // some code that returns Y 

// function 
def foo: X => Y = (x: X) => // some code that returns Y 

我刻意用def的功能也提出一个观点(为了防止读者从制作VAL-DEF错误)但使用val定义函数更常见。

+0

您的区别方法和功能之间是主观的。你能提供支持你的假设的文件吗?顺便说一句,我不同意它:)你第二'foo'可能是“返回函数的方法”或“返回函数的函数” – pedromss

+0

谢谢你的解释。 – philantrovert

+0

我还有另外一个问题。你说可变参数调用_is在一个简单的'Seq'_下面,然后为什么我不能直接将'Seq(1,2,3)'传递给'func1'? – philantrovert

相关问题