2017-07-22 54 views
1

我看到这个代码在使用播放框架使用创建对象并产生

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) 
) 

的应用程序,我不知道如果我的理解使用循环只是创建选项的原因[(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) 
+2

“压缩”不适用于循环 – cchantep

+0

@cchantep我认为它的理解和它是一个循环。看到这个https://alvinalexander.com/scala/scala-for-comprehension-syntax-for-yield-loop-examples – Programmer

+0

'for'是一元组合,而不是循环(这只是一个特定的情况)。首先看看网络教程 – cchantep

回答

2

理解允许您以方便的方式处理多个Option

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

也:如果一个值分别为None如下代码会失败,但for你可以做

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

只是为了更详细地解释这个代码,上面的代码被编译器转换成以下(这是它解决了Option):一个for的C

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

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

+0

你是对的......它是“理解” – Programmer