从Play框架zentask示例中了解Scala函数

时间:2013-07-31 01:23:31

标签: scala playframework-2.0

这是Application.scala中zentask示例中的一个函数。 我正试图理解它......

f:=>字符串是什么意思?

f:=>的链接怎么样? String =>请求[AnyContent] =>结果

/** 
 * Action for authenticated users.
 */
def IsAuthenticated(f: => String => Request[AnyContent] => Result) = 
       Security.Authenticated(username, onUnauthorized) { user =>
       Action(request => f(user)(request))
}

2 个答案:

答案 0 :(得分:3)

fn: => String形式的参数表示返回(或是)String的'generator'(函数或值),因此,例如,您可能将方法定义为

def myMethod(fn: => String): String = "Fn output = " + fn

并按如下方式调用它(我在这里使用的返回类型通常可以由编译器推断,我只是为了教学目的而添加它们):

def myFn: String = "Hello!"
// Alternatively: def myFn(): String = "Hello!"
// or: val myFn: () => String = "Hello!"
// or most simply: val myString = "Hello!"

val output = myMethod(myFn) // output = "Fn output = Hello!"

在此基础上,我们可以定义一个方法,该方法接受一个将String转换为Int的函数,例如:

def my2ndMethod(fn: String => Int): Int = fn("4")

并按如下方式调用:

def my2ndFn(input: String) = 5 * input.toInt
// Alternatively: val my2ndFn: String => Int = input => 5 * input.toInt

val output2 = my2ndMethod(my2ndFn _) // output2 = 20

在你提供的情况下,你有一个更复杂的实体:返回(或者是)一个函数的东西,它接受一个String并返回另一个函数,该函数又接受Request[AnyContent]并且(最终)返回一个结果(p!)。

您还可以将此视为采用如下定义和使用的函数:

def authFn(username: String)(request: Request[AnyContent]): Result

val authenticatedResult = IsAuthenticated(authFn _)

答案 1 :(得分:1)

实际上,弄清楚运营商的关联方式有点棘手:

f: => String => Request[AnyContent] => Result

相同
f: (=> String) => (Request[AnyContent] => Result)

所以f是一个函数,它接受=> String并返回一个接受请求并返回结果的函数。正如我在评论中指出的那样,请查看Need plain english translation of the following scala snippet,了解一些正在发生的事情。

那么为什么=> String作为第一个参数而不仅仅是String?我的猜测是,如果你打算让用户传递一个函数,该函数的第一个参数按名称(意味着每次需要时都会对它进行评估)。

所以说你有方法g

def g(s: => String): String => String = arg => s + arg

如果你想编写一个以m方法作为参数的方法g,那么你需要这样写:

def m(f: (=> String) => (String => String)) = f("a")("b")
m(g) // compiles

如果你这样写:

def n(f: String => (String => String)) = f("a")("b")
n(g) // does not compile
// found   : => String => (String => String)
// required:    String => (String => String)