我需要在一次调用中获得一个包含3个其他案例类的完整案例类。但是,根据用户凭据,他们可能会或可能不会访问该案例类的某些部分。
下面是我当前的操作方式(它有效)。正在拨打电话,但随后清除了未经授权的案件类别。理想情况下,如果它们没有适当的凭据,我想停止通话(由于带宽低),并返回无。
持久性实体服务调用需要一个Option [PersonOne]和Option [PersonTwo],因此.ask必须返回该值,否则它表示正在返回一个对象且不会编译。
override def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
for {
g <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
h <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne) //if (credOne) **this 'if' does not work**
s <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo)
} yield {
val x: Option[PersonOne] = if (credOne == Some(true)) h else None
val y: Option[PersonTwo] = if (credTwo == Some(true)) s else None
CompletePerson(g.get, x, y)
//TODO catch if no employee is returned
//throw NotFound (s"Person not Found with $id");
}
}
答案 0 :(得分:1)
这是函数的一个版本,如果适当的凭据值为ask
,则只会调用Some(true)
:
override def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
CompletePerson(
registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral).get,
credOne.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne)),
credTwo.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo))
)
}
关键部分是这样:
credX.filter(_ == true).flatMap(...)
credX
是None
,它将返回None
credX
包含false
,它将返回None
credX
是Some(true)
,那么flatMap
将调用ask
函数ask
返回None
,则表达式将返回None
,否则它将返回Some[PersonX]
我对某些数据类型不清楚,但是我认为这应该使您了解如何处理此代码。 (例如,裸露的.get
看起来很危险,因为它可能引发异常)
我解决了filter(_)
的一个问题,应该是filter(_ == true)
。
看起来ask
实际上返回了Option[Option[T]]
,在这种情况下,这可能更接近于所需的条件。
def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
for {
g <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
gen <- g
} yield {
val p1 = credOne.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne))).flatten
val p2 = credTwo.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo))).flatten
CompletePerson(gen, p1, p2)
}
}
答案 1 :(得分:0)
我不确定您要问什么,但是您是否担心
registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
返回None
,您将继续拨打昂贵的.ask
电话吗?正如我们从中看到的那样,不会发生的变化
def giveMeSome = {println("giving you Some"); Some(1)}
def giveMeNone = {println("giving you None"); None}
def giveMeSomeMore = {println("giving you Some more"); Some(2)}
val ans = for {
a <- giveMeSome
f <- giveMeNone
q <- giveMeSomeMore
} yield (a, f, q)
println(ans)
可打印
giving you Some
giving you None
None
我们还可以看到,在这种情况下,您会得到None
的回信。我无法确定您是否想要None
或引发错误。如果您要输入错误,则可以包装上面的内容
答案 2 :(得分:0)
我没有完全解决您的问题,但是根据我的理解,您想先检查credOne == Some(true)&& credTwo == Some(true),然后继续进行其他操作,否则返回None
override def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean])
=
for {
cone <- credOne
ctwo <- credTwo
if cone
if ctwo
} yield {
ServerServiceCall { _ =>
for {
g <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
h <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne)
s <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo)
if g.isDefined
} yield {
CompletePerson(g.get, h, s)
}
}