Scala 贷款模式,可选函数参数 [英] scala loan pattern, optional function param

查看:38
本文介绍了Scala 贷款模式,可选函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个贷款模式,它应用一个函数 n 次,其中 'i' 是递增变量.偶尔",我希望传入的函数可以访问 'i'....但我不想要求传入的所有函数都需要定义一个参数来接受 'i'.下面的例子...

I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...

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 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()}
}

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

(not sure how it is related to the loan pattern)

编辑 评论中要求的很少解释.

Edit Little explanation as requested in comment.

不确定您对 Scala 的了解和不了解以及您在该代码中不了解的内容.很抱歉,如果我只是指责显而易见的事情.

Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.

首先,Scala 程序由特征/类(也是单例对象)和方法组成.所做的一切都是通过方法完成的(将构造函数放在一边).函数(与方法相反)是各种 FunctionN 特征(N 是参数的数量)的(子类型)实例.它们中的每一个都有作为实际实现的 apply 方法.如果你写

First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention. If you write

val inc = {i: Int => i + 1}

它被脱糖

val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}

(定义一个匿名类扩展Function1,使用给定的apply方法并创建一个实例)

(defines an anonymous class extending Function1, with given apply method and creating an instance)

所以写一个函数比一个简单的方法更重要.此外,您不能重载(几个具有相同名称的方法,签名不同,就像我上面所做的那样),也不能使用命名参数或参数的默认值.

So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.

另一方面,函数是第一类值(它们可以作为参数传递,作为结果返回)而方法不是.它们会在需要时自动转换为函数,但是这样做时可能会有一些边缘情况.如果一个方法仅用作函数值,而不是作为方法调用,那么编写函数可能更好.

On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.

函数 f 及其 apply 方法,使用 f(x) 而不是 f.apply(x)(这也有效),因为 Scala 的 desugars 函数将值(值后跟括号和 0 个或多个参数)上的符号调用到方法 apply 的调用.f(x)f.apply(x) 的语法糖.无论 f 的类型如何,这都有效,它不需要是 FunctionN 之一.

A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.

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

What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.

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

Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.

这篇关于Scala 贷款模式,可选函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆