【问题标题】:Create object using for and yield使用 for 和 yield 创建对象
【发布时间】:2017-12-28 17:57:39
【问题描述】:

我在一个使用 Play 框架的应用程序中看到了这段代码

val credentials : Option[(ConsumerKey, RequestToken)] = for {
  apiKey <- Play.configuration.getString("twitter.apiKey")
  apiSecret <- Play.configuration.getString("twitter.apiSecret")
  token <- Play.configuration.getString("twitter.token")
  tokenSecret <- Play.configuration.getString("twitter.token")
} yield (
  ConsumerKey(apiKey, apiSecret),
  RequestToken(token, tokenSecret)
)

我不确定我是否理解使用 for 循环来创建 Option[(ConsumerKey, RequestToken)] 对象的原因。为什么要选择使用“for循环”来做到这一点?

为什么不这样?

val apiKey = Play.configuration.getString("twitter.apiKey")
val apiSecret = Play.configuration.getString("twitter.apiSecret")
val token = Play.configuration.getString("twitter.token")
val tokenSecret = Play.configuration.getString("twitter.token")

val tuple: (ConsumerKey, RequestToken) = (ConsumerKey(apiKey.get, apiSecret.get), RequestToken(token.get, tokenSecret.get))
val credentials2 : Option[(ConsumerKey, RequestToken)] = Option(tuple)

【问题讨论】:

  • “用于压缩”不是用于循环
  • @cchantep 我认为它的理解是一个循环。看到这个alvinalexander.com/scala/…
  • for 用于单子组合,而不是循环(这只是一种特定情况)。先看看网上的教程
  • 它是一个循环,它的压缩,它的理解......不,它是 Super Scala :)

标签: scala playframework-2.0


【解决方案1】:

For comprehension 允许您以方便的方式处理多个Option。如果其中一个值为None,您的代码将失败,但使用for,您可以执行以下操作:

scala> for {a <- Some("s1"); b <- Some("s2")} yield (a, b)
res1: Option[(String, String)] = Some((s1,s2))

还有:

scala> for {a <- Some("s1"); b <- None} yield (a, b)
res2: Option[(String, Nothing)] = None

为了更详细地解释这段代码,上面的代码被编译器翻译成下面的代码(这就是它解析Option的方式):

Some("s1").flatMap { a => Some("s2").map { b => (a, b) } } 

【讨论】:

    【解决方案2】:

    for 理解(这是正确的术语)的一个优点是它在第一次失败时终止。例如,如果没有配置apiSecret,则不会尝试获取tokentokenSecret,当然也不会调用ConsumerKey()RequestToken()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 2016-07-11
      • 2015-06-23
      • 2012-12-27
      • 2020-09-28
      相关资源
      最近更新 更多