Play Framework表单中的Scala奇怪类型错误

Posted

技术标签:

【中文标题】Play Framework表单中的Scala奇怪类型错误【英文标题】:Scala strange type error in Play Framework form 【发布时间】:2016-03-30 09:18:56 【问题描述】:

我有这个代码:

package deliveries.NewPost
import play.api.data._
import play.api.data.Forms._

case class NewPostValidator(town: String, number: Int)

object NewPost extends Delivery
  def form[NewPostValidator](): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText,
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply))

在编译时它给了我一个奇怪的错误:

类型不匹配; [错误] 发现: play.api.data.Mapping[deliveries.NewPost.NewPostValidator] [错误] 必需:play.api.data.Mapping[NewPostValidator]

基本上相同的类显示有完整路径和没有完整路径。 会是什么?

我将阐明我想要实现的目标: 我希望每个扩展特征的类都有方法“form”,它返回带有一些验证器的 Form。为此,我创建了 trait:

trait Delivery 
  def form[T](): Form[T]

并尝试在我的班级中实现此方法。

【问题讨论】:

【参考方案1】:

def form[NewPostValidator] 就像说def form[T],只是使用了不同的标识符。编译器不会将方法主体中的 NewPostValidator 视为“真正的”NewPostValidator,而是将其视为您在 def form[NewPostValidator] 中声明的虚构类型 NewPostValidator。

解决方案:

使用 [T] 而不是您的方法参数化您的 trait,并让您的类使用特定类型扩展 trait。

trait Delivery[T] 
  def form(): Form[T]


object NewPost extends Delivery[NewPostValidator] 
  def form(): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText,
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply))

【讨论】:

谢谢@slouc。你说的对。我想做的是使函数与特征兼容,该函数为 def form[T](): Form[T] 所以,我需要这个 [NewPostValidator] 部分,但不明白如何使它工作 如果该特征中的方法是 def form[T](): Form[T] 并且您正在扩展它(因此您需要实现方法形式),那么该方法需要保留相同的签名。您所做的只是将“T”重命名为“NewPostValidator”。如果你想“专门化”该方法不适用于任何 T,而只是 NewPostValidator,那么它不再是同一个函数(意思是,如果你正在实现或覆盖方法 def form[T](): Form[T] 那么你必须使用相同的签名;您不能将其范围缩小到仅适用于 NewPostValidator)。 尝试通过提供更多代码(包括该特征)来更详细地解释您的问题。您现在知道为什么您的尝试不起作用,但我无法告诉您如何实现您想要实现的目标,因为我没有完整的画面。例如,这是您可以做的另一件事 - 如果您是该特征的作者,请将 [T] 从方法参数移动到类参数,例如trait Foo[T],然后让你的类扩展 Foo[NewPostValidator]。这样,方法可以分别具有签名def form(): Form[T]def form(): Form[NewPostValidator] 谢谢@slouc 我已经澄清了我原来的问题。我有我的错误,但了解如何正确地实现我想要的。 实际上,您将参数移动到类的建议确实有效。但是可以在函数中使用参数吗?

以上是关于Play Framework表单中的Scala奇怪类型错误的主要内容,如果未能解决你的问题,请参考以下文章

Scala + Play Framework + Slick - Json 作为模型字段

Play Framework 2.4 在 Scala 模板中使用注入变量

Netbeans + Scala + play-framework:找不到 index.html

如何使用 Scala 登录 Play Framework?

Play framework + Scala:使用动作组合注入依赖

在 Play Framework 2.4 中为 Scala 实现 Akka