5

我有一个返回对象的表达式,并且我只想在某个布尔条件为真时才对结果对象调用一个方法。我想在 val.

一种方法是使用临时变量,例如在下面的示例中,其中List(3, 1, 2)(可能很复杂)表达式返回一个对象,list是临时变量,并且.sorted是我想要有条件地调用的方法:

import scala.util.Random

val condition = Random.nextBoolean
val result = {      
  var list = List(3, 1, 2);
  if (condition) list = list.sorted
  list
}

这样做的规范方法是什么,也许使用临时变量?

注意

if (condition) List(3, 1, 2).sorted else List(3, 1, 2)

不太令人满意,因为List(3, 1, 2)通常可能是一个我不想重复的复杂表达式。

不幸的是,这是我发现的一种方法,它涉及提供显式类型(并且比如上所述引入临时 var 更长且更复杂):

val condition = Random.nextBoolean
val result =
  (
    if (condition)
      {l: List[Int] => l.sorted}
    else
      identity(_: List[Int])
  ).apply(List(3, 1, 2))

我怀疑一定有一种我无法识别的更整洁的方式。

更新:一个稍微不那么难看的方法,不幸的是仍然需要明确的类型信息:

val condition = Random.nextBoolean    
val result = {
    l: List[Int] => if (condition) l.sorted else l
  }.apply(List(3, 1, 2))
4

2 回答 2

10

您可以使用正向管道运算符:

implicit class PipedObject[A](value: A) {
  def |>[B](f: A => B): B = f(value)
}

scala> List(3, 1, 2) |> (xs => if (true) xs.sorted else xs)
res1: List[Int] = List(1, 2, 3)
于 2013-04-04T22:32:05.507 回答
5

开始Scala 2.13,标准库现在提供链接操作pipe,可用于转换/管道具有感兴趣函数的值,从而避免中间变量:

import scala.util.chaining._

List(3, 1, 2).pipe(list => if (condition) list.sorted else list)
于 2018-10-07T09:47:39.230 回答