def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(不知道和贷款模式有什么关系)
Edit评论中要求的解释很少。
不确定你对 scala 知道什么、不知道什么,以及在代码中你不理解什么。很抱歉,如果我只是对显而易见的事情进行了阐述。
首先,scala 程序由特征/类(也是单例对象)和方法组成。所做的一切都是通过方法完成的(将构造函数放在一边)。函数(与方法相反)是各种 FunctionN 特征(N 是参数数量)的实例(子类型)。它们每个都有一个 apply 方法,它是实际的实现。
如果你写
val inc = {i: Int => i + 1}
它被脱糖为
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(定义一个匿名类扩展Function1
,使用给定的 apply 方法并创建一个实例)
所以写一个函数比写一个简单的方法更有分量。此外,您不能进行重载(多个具有相同名称的方法,其签名不同,正如我上面所做的那样),也不能使用命名参数或参数的默认值。
另一方面,函数是第一类值(它们可以作为参数传递,作为结果返回),而方法则不是。它们会在需要时自动转换为函数,但是这样做时可能会出现一些边缘情况。如果一个方法只是用作函数值,而不是作为方法调用,那么编写一个函数可能会更好。
一个功能f
,以其apply
方法,被调用为f(x)
而不是f.apply(x)
(这也有效),因为 scala 脱糖函数调用符号对值(值后跟括号和 0 个或多个参数)调用方法apply
. f(x)
是语法糖f.apply(x)
。无论什么类型,这都有效f
,它不必是其中之一FunctionN
.
withLoaner 所做的是返回一个对象(匿名类型,但可以单独定义一个类并返回它的实例)。该对象有两个apply
方法,一种接受Int => String
,另一个是() => String
。当你这样做时withLoaner(n)(f)
它的意思是withLoaner(n).apply(f)
。选择适当的应用方法,如果f
具有其中之一的正确类型,否则编译错误。
以防万一你想知道withLoaner(n)
并不意味着withLoaner.apply(n)
(或者它永远不会停止,这也可能意味着withLoaner.apply.apply(n)
),因为 withLoaner 是一个方法,而不是一个值。