函数与Scala中的方法
我正在看Runar Bjarnason介绍初学者的函数式编程 ,14:45他定义了一个方法:
def isDivisibleBy(k: Int): Int => Boolean = i => i % k == 0
和一个function:
val isEven = isDivisibleBy(2)
定义isEven作为一个函数而不是一个方法有什么好处和坏处?
我已经阅读了Scala函数与方法以及Scala中的方法和函数之间的区别 ,并且我理解语义差异,但是我不知道在这种情况下,为什么函数可能会或可能不会使用方法更好:
def isEven = isDivisibleBy(2)
在引擎盖下,function和方法还有其他的区别。 一般来说,一个普通的方法产生的开销比一个函数(技术上是一个具有apply方法的对象)less。
然而,如果你不关心这些差异,并把def , val和var当作不同语义的字段 ,那么简单地说就是def每次被调用的时候评估,而val只评估一次。
因此, val isEven = isDivisibleBy(2)应该在其定义期间调用isDivisibleBy(2)并指定isDivisibleBy(2)的结果。 例如,它取代了k
def isDivisibleBy(k: Int): Int => Boolean = i => i % k == 0
与2并分配最终expression式的结果(在这种情况下,只有一个expression式):
val isEven: Int => Boolean = i => i % 2 == 0
def isEven另一方面没有这样的评价,并且每次都会调用isDivisibleBy(2)。
这意味着,稍后当您执行代码时, isEven(11)在val情况下生成
11 % 2 == 0
如果是def ,你会有的
isDivisibleBy(2)(11)
只有在评估isDivisibleBy你会得到结果。
你可以添加一些debugging代码到isDivisibleBy看看不同之处:
def isDivisibleBy(k: Int): Int => Boolean = { println("evaluating isDivisibleBy") i => i % k == 0 }
我想在这里谈谈另一点。 这将isEven定义为一种方法:
def isEven = isDivisibleBy(2)
而且这个定义isEven一个方法:
val isEven = isDivisibleBy(2)
在这两种情况下, isEven都是一种当被调用时返回一个函数的方法。
在第一种情况下, isDivisible(2)每次调用isEven被调用。 例如,这个调用是isDivisible(2)三次:
def isEven = isDivisibleBy(2) List(1,2,3).filter(isEven)
在第二种情况下, isDivisible(2)被调用一次(在构build时,或者当定义中的行被执行时),并且每次调用isEven时isEven检索该值。 下面的例子只调用isDivisible(2) :
val isEven = isDivisibleBy(2) List(1,2,3).filter(isEven)
我认为,定义函数的主要方法是将函数作为val来向观众展示函数可以这样定义。 那么很明显,函数就像scala中的其他所有东西一样。 但在非演示编程的世界中,不需要写入函数作为val 。
方法def isDivisibleBy(k: Int): Int => Boolean返回一个函数,它接受一个Int( i )作为参数并返回一个布尔值( i % k == 0 )。
val isEven = isDivisibleBy(2)另一方面是存储由isDivisibleBy(2)返回的函数的字段。 如果使用def而不是val那么每次调用isEven方法时都会调用isDivisibleBy方法,但现在只调用一次,结果存储在字段中。
您可以通过编写def isEven(i: Int): Boolean = i % 2 == 0来实现相同的结果def isEven(i: Int): Boolean = i % 2 == 0
我认为这个例子的意义在于,你可以有返回其他函数的函数,并且可以把函数存储为对象,然后像调用传统的方法一样调用它们。 上面的代码也和currying非常相似,所以这也可能是这个例子演示的一个东西(尽pipe它没有使用Scala的currying语法 )。