我有一个贷款模式,应用函数n次,其中'i'是递增变量."偶尔",我希望传入的函数可以访问'i'....但我不想要求传入的所有函数都要求定义一个param来接受'i'.以下示例......
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
Run Code Online (Sandbox Code Playgroud)
Did*_*ont 11
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()}
}
Run Code Online (Sandbox Code Playgroud)
(不确定它与贷款模式有何关联)
根据评论中的要求编辑一些小解释.
不确定你知道什么,不知道scala以及你在该代码中没有看到的东西.很抱歉,如果我只是显而易见的话.
首先,scala程序由traits/classes(也是单例对象)和方法组成.所做的一切都是通过方法完成的(将构造函数放在一边).函数(与方法相对)是各种FunctionN特征(的子类型)的实例(N个参数的数量).它们中的每一个都具有作为实际实施的应用方法.如果你写
val inc = {i: Int => i + 1}
Run Code Online (Sandbox Code Playgroud)
它很沮丧
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
Run Code Online (Sandbox Code Playgroud)
(Function1使用给定的apply方法和创建实例定义扩展的匿名类)
因此,编写函数比简单方法更重要.此外,您不能重载(具有相同名称的多个方法,不同于签名,正如我上面所做的那样),也不能使用命名参数或参数的默认值.
另一方面,函数是第一个类值(它们可以作为参数传递,作为结果返回)而方法不是.它们会在需要时自动转换为函数,但在执行此操作时可能会出现一些边缘情况.如果一个方法仅用作函数值,而不是作为方法调用,那么编写函数可能更好.
一个函数f及其apply方法被调用f(x)而不是f.apply(x)(也是有效的),因为scala desugars函数调用符号对一个值(值后跟括号和0或更多args)调用方法apply.f(x)是语法糖f.apply(x).这适用于任何类型的f,它不需要是其中之一FunctionN.
在withLoaner中所做的是返回一个对象(匿名类型,但是可以单独定义一个类并返回它的实例).该对象有两种apply方法,一种接受a Int => String,另一种接受a () => String.当你这样做withLoaner(n)(f)意味着withLoaner(n).apply(f).如果f其中一个具有正确的类型,则选择适当的apply方法,否则编译错误.
万一你怀疑withLoaner(n)并不意味着withLoaner.apply(n)(或者它永远不会停止,那也可能意味着withLoaner.apply.apply(n)),因为withLoaner是一种方法,而不是一种价值.
| 归档时间: |
|
| 查看次数: |
1446 次 |
| 最近记录: |