【问题标题】:Scala strange type error in Play Framework formPlay Framework表单中的Scala奇怪类型错误
【发布时间】: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]
}

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

【问题讨论】:

    标签: scala playframework


    【解决方案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 我已经澄清了我原来的问题。我有我的错误,但了解如何正确地实现我想要的。
    • 实际上,您将参数移动到类的建议确实有效。但是可以在函数中使用参数吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多