【问题标题】:Scala transformations斯卡拉转换
【发布时间】:2016-02-14 00:04:45
【问题描述】:

我是 Scala 的新手,我想问一个简单的问题。

我有一个返回Future[Option[T]的函数

def findOne(query: JsObject)(implicit reader: Reads[T]): Future[Option[T]] = {
    Logger.debug(s"Finding one: [collection=$collectionName, query=$query]")
    collection.find(query).one[T]
}

我必须返回Future[Option[PasswordInfo]]

我试过了:

def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] = {

    val result = find(Json.obj("loginInfo.providerID" -> loginInfo.providerID, "loginInfo.providerKey" -> loginInfo.providerKey))

    result.onSuccess{
      case something => Future.successful(Some(something).getOrElse(None))
    }
}

我的班级:

case class PersistentPasswordInfo(
       loginInfo: LoginInfo,
       authInfo: PasswordInfo
       ) extends TemporalModel {
  override var created: Option[DateTime] = _
  override var updated: Option[DateTime] = _
  override var _id: Option[BSONObjectID] = _
}

【问题讨论】:

  • Future.successful(Some(something).getOrElse(None)) 是错误的。 Future.successful(Some(something)) 应该足够了,只要是 PasswordInfo
  • 有些东西是 PersistentPasswordInfo,我需要 authInfo,它在我的课堂内
  • Future.successful(Some(something.authInfo)) ?
  • 无法解析.authInfo
  • 在包含 findOne 函数的类上定义的 T 是什么?

标签: mongodb scala silhouette


【解决方案1】:

您需要映射 Future 以获取 Option,然后映射 Option 以获取 PersistedPasswordInfo

def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] = {

    val result = find(Json.obj("loginInfo.providerID" -> loginInfo.providerID, "loginInfo.providerKey" -> loginInfo.providerKey))

    result.map(opt => opt.map(ppi => ppi.authInfo))
}

Future 和 Option 都是 Functor,它们实现了一个具有类似以下签名的方法映射(假设包含 Future 的类型 arg 是 A):

def map[B](f: A => B): Future[B]

所以上面的代码通过应用一个函数 Option[PersistentPasswordInfo] => Option[PasswordInfo]

来改变 Future

该函数是通过使用函数 PersistentPasswordInfo => PasswordInfo 对包含的 Option 应用映射来创建的

【讨论】:

  • 您可以使用 _ 来缩短它,但我想展示在每个步骤中映射的仿函数。较短的版本是 result.map(.map(.authInfo))
  • 谢谢。但是你能解释一下吗?如果findOne 返回空值会怎样? ppi.authInfo 将如何执行?为什么它不会返回空指针异常? (试图访问一个空对象的字段)
  • 我收到[error] both method defaultContext in object Implicits of type => scala.concurrent.ExecutionContext [error] and method ec in trait ContextHelper of type => scala.concurrent.ExecutionContext [error] match expected type scala.concurrent.ExecutionContext [error] result.map(opt => opt.map(ppi => ppi.authInfo)
  • 尝试在实现 find 的文件中导入 ExecutionContext.Implicits.global。处理 Futures 的操作需要一个 ExecutionContext,这是默认的。
  • 对不起,它有效。这是我的进口产品之一。谢谢
猜你喜欢
  • 2013-02-25
  • 2011-09-16
  • 2016-01-31
  • 2017-03-17
  • 2017-10-23
  • 1970-01-01
  • 2017-01-19
  • 2021-06-09
  • 2021-11-06
相关资源
最近更新 更多