我已经将Play Framework控制器简化为最小化,因此它显示了问题,并且我嘲笑了Play,所以这个程序本身已经完成了。代码是问题在顶部,模拟遵循;你可以忽略它们 - 它们就是这样的样本编译。为方便起见,我为此代码示例制作了git repo。
package com.micronautics.blah
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
object LazyController extends Controller {
case class SecureActionInfo[SA <: SecuredArtifact](allowedRoles: Seq[Role], block: SA => RequestHeader => Html)
val allCourseTranscripts = (course: Course) => { implicit request: RequestHeader =>
Html(printTitlePage(course) + course.allTranscripts(showTitlePage = false))
}
val secureFetchActions = Map[String, SecureActionInfo[_]](
"AllCourseTranscripts" -> SecureActionInfo(Nil, allCourseTranscripts)
)
def fetchByArtifact[SA <: SecuredArtifact](tabName: String, artifact: SA)(implicit request: RequestHeader) =
Future {
val actionInfo: SecureActionInfo[_] = secureFetchActions(tabName)
val result: Html = if (actionInfo.allowedRoles.nonEmpty) {
(for {
user <- Model.maybeCurrentUser
} yield actionInfo.block(artifact)(request)).getOrElse(Html("Not authorized"))
} else actionInfo.block(artifact)(request)
Ok(result)
}
}
trait SecuredArtifact
class Lecture extends SecuredArtifact
class Course extends SecuredArtifact {
def allTranscripts(showTitlePage: Boolean) = "Title page"
}
// Mocks follow
case class Role(name: String)
trait Controller
trait RequestHeader
case class Html(text: String)
case class User(name: String)
case class Ok(name: Html)
case object Model {
def maybeCurrentUser = Some(User("mary"))
}
object `package` {
def printTitlePage(course: Course) = "Title page"
}
Scala编译器输出是:
[error] /var/work/training/experiments/lazyController/src/main/scala/com/micronautics/blah/LazyController.scala:23: type mismatch;
[error] found : artifact.type (with underlying type SA)
[error] required: _$2
[error] } yield actionInfo.block(artifact)(request)).getOrElse(Html("Not authorized"))
[error] ^
[error] /var/work/training/experiments/lazyController/src/main/scala/com/micronautics/blah/LazyController.scala:24: type mismatch;
[error] found : artifact.type (with underlying type SA)
[error] required: _$2
[error] } else actionInfo.block(artifact)(request)
[error] ^
似乎我没有正确指定允许Course
作为SA
的实例。
答案 0 :(得分:0)
SecureActionInfo[_]
表示类型_
未知(您可以将其完整地写为SecureActionInfo[X] forSome { type X }
)。因此,没有办法知道SA
是否是正确的类型,这就是编译器错误所说的。
您可能希望actionInfo
成为SecureActionInfo[SA]
而不是SecureActionInfo[_]
。您必须将其从Map
中转出或使用不同的数据结构来保留类型信息。