发现错误:artifact.type(带底层类型SA)需要错误:_ $ 2

时间:2015-02-11 21:53:03

标签: scala

我已经将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的实例。

1 个答案:

答案 0 :(得分:0)

SecureActionInfo[_]表示类型_未知(您可以将其完整地写为SecureActionInfo[X] forSome { type X })。因此,没有办法知道SA是否是正确的类型,这就是编译器错误所说的。

您可能希望actionInfo成为SecureActionInfo[SA]而不是SecureActionInfo[_]。您必须将其从Map中转出或使用不同的数据结构来保留类型信息。