我在使用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)
答案 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
,则不会尝试获取token
或tokenSecret
,当然也不会调用ConsumerKey()
或{{1} }。