使用for和yield创建对象

时间:2017-07-22 20:07:34

标签: scala playframework-2.0

我在使用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 loop”来执行此操作?

为什么不呢?

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)

2 个答案:

答案 0 :(得分:2)

为了理解,您可以方便地处理多个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) } } 

答案 1 :(得分:1)

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