.scala 中的替代品 [英] .with alternative in scala

查看:62
本文介绍了.scala 中的替代品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自 Groovy,它在每个接受单参数闭包的类型上都有一个 .with 方法;参数是调用 .with 方法的对象.这允许使用一种非常酷的技术来扩展函数链接功能,从而免除您引入临时变量、分解代码的义务,使其更易于阅读并做其他一些事情.

I come from Groovy and it has a .with method on every type which accepts a single-argument closure; the argument is the object on which the .with method is being called. This allows a very cool technique of extending the functional chaining capabilities, which releases you from obligation to introduce temporary variables, factors your code, makes it easier to read and does other niceties.

我希望能够做这样的事情:

I want to be able to do something like this:

Seq(1, 2, 3, 4, 5)
  .filter(_ % 2 == 0)
  .with(it => if (!it.isEmpty) println(it))

代替

val yetAnotherMeaninglessNameForTemporaryVariable = 
  Seq(1, 2, 3, 4, 5).filter(_ % 2 == 0)
if (!yetAnotherMeaninglessNameForTemporaryVariable.isEmpty) 
  println(yetAnotherMeaninglessNameForTemporaryVariable)

换句话说,在第一个示例中,.with 有点类似于 .foreach,但它不是遍历对象的项目,而是在对象本身.所以 it 等于 Seq(1, 2, 3, 4, 5).filter(_ % 2 == 0).

In other words in the first example the .with is kinda similar to .foreach but instead of iterating thru the items of the object it is being called once on the object itself. So it is equal to Seq(1, 2, 3, 4, 5).filter(_ % 2 == 0).

因为我很惊讶在 Scala 中没有找到类似的东西,所以我的问题是:

Since I was very surprised not to find anything like that in Scala, my questions are:

  • 我错过了什么吗?
  • Scala 是否有其他替代技术?
  • 如果不是,那么在 Scala 中没有实现此功能有什么合理的理由吗?

更新:已在 Scala 问题跟踪器上发布了适当的功能请求:https://issues.scala-lang.org/browse/SI-5324.请投票和推广

Update: An appropriate feature request has been posted on the Scala issue tracker: https://issues.scala-lang.org/browse/SI-5324. Please vote and promote

推荐答案

标准库中没有这样的方法,但是定义自己的方法并不难.

There doesn't exist any such method in the standard library, but it's not hard to define your own.

implicit def aW[A](a: A) = new AW(a)
class AW[A](a: A) {
  def tap[U](f: A => U): A = {
    f(a)
    a
  }
}

val seq = Seq(2, 3, 11).
          map(_ * 3).tap(x => println("After mapping: " + x)).
          filter(_ % 2 != 0).tap(x => println("After filtering: " + x))

(回应评论)

哦,我误会了.你需要的东西在 Scalaz 库中.它的名称为 |>(称为管道操作符).这样,您的示例将如下所示:

Oh, I misunderstood. What you need is there in the Scalaz library. It comes under name |> (referred to as pipe operator). With that, your example would look like shown below:

Seq(1, 2, 3, 4, 5).filter(_ % 2 == 0) |> { it => if(!it.isEmpty) println(it) }

如果你不能使用Scalaz,你可以自己定义操作符:

If you cannot use Scalaz, you can define the operator on your own:

implicit def aW[A](a: A) = new AW(a)
class AW[A](a: A) {
  def |>[B](f: A => B): B = f(a)
}

在现有类型上使用有用的方法并不是一个坏习惯.您应该谨慎地使用隐式转换,但我认为这两个组合器很常见,他们的皮条客是有道理的.

And it's not a bad practice to pimp useful method(s) on existing types. You should use implicit conversions sparingly, but I think these two combinators are common enough for their pimps to be justifiable.

这篇关于.scala 中的替代品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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