我只是在play2-auth示例中偶然发现了这一行:

val remember = request.tags.get("rememberme").exists("true" ==) || //...

我了解它的作用(检查map标签是否包含映射"rememberme" -> "true"),但是我发现exists()中的谓词很有趣,而且从未见过以此方式编写的谓词。

在REPL中对此进行了一些测试之后,我得出的结论是,它与
.exists("true" == _)
// or even longer:
.exists(s => "true" == s)

这种表示法显然还可以与其他单参数函数一起使用,而不仅仅是谓词:
scala> Some("world").map("Hello " +)
res0: Option[String] = Some(Hello world)

为什么这里的参数可以省略?最终,它似乎节省了一个字符,即下划线。对于我来说,引入一种语言功能似乎有点奇怪。是否有与此相关的大图?

最佳答案

可以将其省略,因为方法会自动转换为函数。有人会说,只会对对象上的方法或导入到范围中的方法执行此操作,因此您无需指定它们所在的对象。但这只是说得更一致:如果您命名一个方法,并且需要一个函数,则编译器会为您转换它。

因此,"Hello ".+命名了一个方法(从技术上讲,是$plusStringOps扩展方法)。从而将其转换为函数。

至于为什么完全允许自动转换而不是总是需要_的原因,这更加主观。如果您使用的是更具功能性的样式,那么会经常使用它,因此最好不要在知道了您的意思(例如_)的情况下让多余的xs.foreach(println)乱扔垃圾。

09-30 21:37
查看更多