为什么我不能解压此 Scala 模式匹配中的值?
Why can't I unpack the value in this scala pattern match?
我正在尝试在 scala 中使用 slick(带有 unicorn)查找用户。这是我的代码:
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
在上面标记的行中,intellij 打印 "type mismatch. Expected DbLoginInfoId, actual Option[DbLoginInfoId]".
我是不是在一个选项中有一个选项,所以 retrievedLoginInfo
实际上是一个 Option[retrievedLoginInfo]
?我怎样才能正确解压,以便我可以访问 retrievedLoginInfo
?
的 ID
我觉得不错。我认为问题中缺少一些信息?
一旦我围绕这段代码填充了足够的上下文,它就会编译。此代码中属于您的部分未更改:
import scala.concurrent.Future
package object foo {
trait LoginInfo {
def providerID: Any
def providerKey: Any
}
abstract class BaseIdRepository[A, B, C](x: Any)
trait IdentityService[A] {
def retrieve(loginInfo: LoginInfo): Future[Option[User]]
}
trait User {
def id: UserId
}
trait UserId
trait Users
def TableQuery[A] = ???
class UserLoginInfoJunctionRepository {
def forB(x: UserId): QueryResult[User] = ???
}
trait DbLoginInfoId
trait DbLoginInfo
trait LoginInfos
trait QueryResult[A] {
def firstOption: Option[A] = ???
}
class Query {
def filter(f: LoginInfo => Boolean): QueryResult[User] = ???
}
val query = new Query()
// ----
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
}
如果你能trim将问题简化为一个最小的例子,那就容易多了。
看起来 LoginInfo
上的 id
是 Option[DbLoginInfoId]
类型,但 forB
需要 DbLoginInfoId
.
您需要映射 retrievedLoginInfo.id
以提取实际值。您可以通过更好的理解来重构整个事物,例如:
for {
retrievedLoginInfo <- loginInfoRepository.find(loginInfo)
id <- retrievedLoginInfo.id
userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
res <- userLoginInfoJunctionRepository.forB(id).firstOption
} yield res
我正在尝试在 scala 中使用 slick(带有 unicorn)查找用户。这是我的代码:
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
在上面标记的行中,intellij 打印 "type mismatch. Expected DbLoginInfoId, actual Option[DbLoginInfoId]".
我是不是在一个选项中有一个选项,所以 retrievedLoginInfo
实际上是一个 Option[retrievedLoginInfo]
?我怎样才能正确解压,以便我可以访问 retrievedLoginInfo
?
我觉得不错。我认为问题中缺少一些信息?
一旦我围绕这段代码填充了足够的上下文,它就会编译。此代码中属于您的部分未更改:
import scala.concurrent.Future
package object foo {
trait LoginInfo {
def providerID: Any
def providerKey: Any
}
abstract class BaseIdRepository[A, B, C](x: Any)
trait IdentityService[A] {
def retrieve(loginInfo: LoginInfo): Future[Option[User]]
}
trait User {
def id: UserId
}
trait UserId
trait Users
def TableQuery[A] = ???
class UserLoginInfoJunctionRepository {
def forB(x: UserId): QueryResult[User] = ???
}
trait DbLoginInfoId
trait DbLoginInfo
trait LoginInfos
trait QueryResult[A] {
def firstOption: Option[A] = ???
}
class Query {
def filter(f: LoginInfo => Boolean): QueryResult[User] = ???
}
val query = new Query()
// ----
class UserRepository extends BaseIdRepository[UserId, User, Users](TableQuery[Users]) with IdentityService[User] {
/**
* Retrieve the User associated with the given LoginInfo, if any. This method
* is required by Silhouette.
* @param loginInfo
*/
override def retrieve(loginInfo: LoginInfo): Future[Option[User]] = {
Future.successful {
val loginInfoRepository = new LoginInfoRepository
loginInfoRepository.find(loginInfo) match {
case Some(retrievedLoginInfo) =>
val userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
// problem here...
userLoginInfoJunctionRepository.forB(retrievedLoginInfo.id).firstOption
case None => None
}
}
}
}
class LoginInfoRepository extends BaseIdRepository[DbLoginInfoId, DbLoginInfo, LoginInfos](TableQuery[LoginInfos]) {
def find(loginInfo: LoginInfo) = query.filter(
l =>
l.providerID == loginInfo.providerID &&
l.providerKey == loginInfo.providerKey
).firstOption
}
}
如果你能trim将问题简化为一个最小的例子,那就容易多了。
看起来 LoginInfo
上的 id
是 Option[DbLoginInfoId]
类型,但 forB
需要 DbLoginInfoId
.
您需要映射 retrievedLoginInfo.id
以提取实际值。您可以通过更好的理解来重构整个事物,例如:
for {
retrievedLoginInfo <- loginInfoRepository.find(loginInfo)
id <- retrievedLoginInfo.id
userLoginInfoJunctionRepository = new UserLoginInfoJunctionRepository
res <- userLoginInfoJunctionRepository.forB(id).firstOption
} yield res