【问题标题】:Bounded generic parameters in Play Framework templatePlay Framework 模板中的有界泛型参数
【发布时间】:2015-04-13 21:46:42
【问题描述】:

如何在 Play Framework 2.3 Java 项目的 Scala 模板中使用有界泛型参数?

我目前有类似的东西:

@(entities: List[_ <: Entity], currentEntity: Entity)

<ul>
    @for(entity <- entities) {
        @if(currentEntity.equals(entity)) {
            <li><strong>@entity</strong></li>
        } else {
            <li>@entity</li>
        }
    }
</ul>

但是,我可以在 entitiescurrentEntity 中使用不同类型的实体来调用它——这不太好。我想做类似的事情:

@[T <: Entity](entities: List[T], currentEntity: T)
...

但这会给我Invalid '@' symbol 作为编译错误。

【问题讨论】:

标签: scala playframework-2.3


【解决方案1】:

正如@m-z 指出的那样,它不受支持(目前)。但是,您可以通过首先将参数编组到 View 对象中来获得所需的类型安全(以另一类类为代价):

case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E)

现在在您的控制器中,加载一个新的 HighlightedListView 实例,而不是直接将参数提供给模板:

 def foo = Action {
  ...
  // Assuming some SubEntity exists, the compiler will enforce the typing:
  val hlv = HighlightedListView[SubEntity](entities, currentEntity)


  Ok(html.mytemplate(hlv))

}

正如评论所述,如果您的类型不对齐,编译器会出错。那么模板的类型可以很松散,因为我们知道我们是安全的:

@(hlv:HighlightedListView[_])

<ul>
    @for(entity <- hlv.entities) {
        @if(hlv.currentEntity.equals(entity)) {
            <li><strong>@entity</strong></li>
        } else {
            <li>@entity</li>
        }
    }
</ul>

您甚至可以利用您的新 View 对象添加帮助方法,这可以使模板更易于阅读,并促进单元测试:

case class HighlightedListView[E <: Entity](entities:List[E], currentEntity:E) {
   def shouldHighlight(e:Any):Boolean = currentEntity.equals(e)
}

导致:

 @if(hlv.shouldHighlight(entity)) {
     <li><strong>@entity</strong></li>
 } else {
     <li>@entity</li>
 }

【讨论】:

  • 对我来说,这只适用于类型成员,而不是类型参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2012-10-09
  • 1970-01-01
相关资源
最近更新 更多