有没有一种方法可以使用类似映射的语法来设置Scala中非映射代码块中的变量?

有没有一种方法可以使用类似映射的语法来设置Scala中非映射代码块中的变量?,scala,Scala,我经常在编写代码时希望计算一个表达式,然后使用与map或fold表达式类似的语法将该表达式的结果作为变量传递给下一个代码块 我想要编写的代码类型与我们在选项或未来所做的类似: Some("foo") map { upper => s"works with $upper"} 但是没有支持映射的对象 一个很好的例子(但不是唯一的例子)是用spray库替换中的Json元素。比如: JsObject(upper.fields + ("obj" -> JsObject( uppe

我经常在编写代码时希望计算一个表达式,然后使用与map或fold表达式类似的语法将该表达式的结果作为变量传递给下一个代码块

我想要编写的代码类型与我们在选项或未来所做的类似:

Some("foo") map { upper => s"works with $upper"}
但是没有支持映射的对象

一个很好的例子(但不是唯一的例子)是用spray库替换中的Json元素。比如:

JsObject(upper.fields +
  ("obj" -> JsObject(
    upper.fields("obj").asJsObject { lower: JsObject => lower.fields +
      ("data" -> JsObject(lower.fields("data")))
    }
  ))
) 
有没有一种方法可以在不使用嵌套匹配的情况下实现这一点

回答1:下面是一个使用Scala 2.12的鼠标库的示例:

def withMouse(upper: JsObject): JsObject = {
  upper
    .|> { upper => println(upper.compactPrint); upper.fields; }
    .|> { upper => upper + ("obj" ->
      upper("obj").asJsObject.fields
        .|> { lower => JsObject(lower + ("data" ->
          lower("data")
        ))}
    )}
    .|> { newmsg => JsObject(newmsg) }
}
回答2:这里是使用库的.pipe方法和Scala 2.13的同一个示例

def withPipe(upper: JsObject): JsObject = {
  upper
    .pipe { upper => println(upper.compactPrint); upper.fields; }
    .pipe { upper => upper + ("obj" ->
      upper("obj").asJsObject.fields
        .pipe { lower => JsObject(lower + ("data" ->
          lower("data")
        ))}
    )}
    .pipe { newmsg => JsObject(newmsg) }
}

听起来你想要
pipe()

从:


如果不是在Scala 2.13上,则存在提供类似链接运算符的

input
  .<|     { println        }
  .<|     { preconditions  }
  .thrush { program        }
  .<|     { postconditions }
  .<|     { println        }

注意如何
谢谢你,马里奥。我在当前的项目中运行Scala 2.12,因此它很有帮助。我看得出。|>和。画眉鸟是可以互换的。这种语法类似于我的爱人的理解。我将在我的原始问题中发布一个例子。我更喜欢使用核心语言能力。管道和水龙头看起来会像我期望的那样工作。我还没有能够让2.13.2的工作表正常工作,所以我无法正确地制作原型。但我会在我的问题中给出一个应该有效的例子。谢谢,@jwvh!谢谢@texasbruce。使用链式(和嵌套式)匹配时,我发现编译器对使用()包装匹配非常挑剔。使用matches可以得到的最紧凑的代码是:
defwithmatch(upper:JsObject):JsObject={((upper-match{case-upper=>upper.fields})match{case-upperf=>{upperf+(“obj”)>(upperf(“obj”).asJsObject.fields匹配{case-lower=>JsObject(lower+(“数据”->lower(“数据”)}))}})匹配{case newmsg=>JsObject(newmsg)}}
看到您有什么不同的做法吗?您是对的,需要括号。这不是一个很好的解决方案。
input
  .<|     { println        }
  .<|     { preconditions  }
  .thrush { program        }
  .<|     { postconditions }
  .<|     { println        }
import mouse.all._
import scala.io.StdIn

case class User(name: String, age: Int, previous: Option[User] = None) {
  def changeName(newName: String): User =
    this.copy(name = newName, previous = Some(this))
}

def preconditions(user: User): Unit = {
  assert(user.name.nonEmpty, "User should have a name")
  assert(user.age >= 0, "User's age should not be negative")
}

def postconditions(`new`: User): Unit = {
  assert(
    `new`.previous.exists(_.name != `new`.name),
    "User should have changed their name details"
  )
}

def program(user: User): User = {
  println(s"Please enter new name for $user")
  val newName = StdIn.readLine()
  user.changeName(newName)
}

val input = User("Picard", 75)