【问题标题】:scala loan pattern, optional function paramscala贷款模式,可选功能参数
【发布时间】:2011-09-08 07:10:22
【问题描述】:

我有一个贷款模式,它应用一个函数 n 次,其中“i”是递增变量。 “偶尔”,我希望传入的函数能够访问'i'......但我不想要求传入的所有函数都需要定义一个参数来接受'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))

【问题讨论】:

  • 与问题无关,但如果你写 def f : (args) => expr 而不是 def f(args) = expr (我不确定我一般会这样做),你可以让 f 成为 val 而不是 def。

标签: scala


【解决方案1】:
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()}
}

(不确定它与贷款模式有什么关系)

编辑评论中要求的一点解释。

不确定您对 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 或更多参数)调用方法applyf(x)f.apply(x) 的语法糖。无论f 的类型如何,它都可以使用,它不需要是FunctionN 之一。

在 withLoaner 中所做的是返回一个对象(匿名类型,但可以单独定义一个类并返回它的一个实例)。该对象有两个apply 方法,一个接受Int =&gt; String,另一个接受() =&gt; String。当您执行withLoaner(n)(f) 时,它的意思是withLoaner(n).apply(f)。如果f 具有其中一个的正确类型,则选择适当的应用方法,否则编译错误。

以防你想知道withLoaner(n) 并不意味着withLoaner.apply(n)(或者它永远不会停止,这也可能意味着withLoaner.apply.apply(n)),因为 withLoaner 是一种方法,而不是一个值。

【讨论】:

  • 这看起来很棒。非常好。你介意添加一点解释这是做什么的吗?另外,您是说 def f(args) = expr 是更常见/更好的做法吗?不知道为什么...
猜你喜欢
  • 1970-01-01
  • 2016-07-28
  • 2023-03-16
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2014-01-16
  • 2012-08-04
相关资源
最近更新 更多