【问题标题】:Case class apply method, What does this syntax means?案例类apply方法,这个语法是什么意思?
【发布时间】:2015-08-17 12:43:31
【问题描述】:

我正在尝试在一个辅助项目中使用 Scala + Play 2.4.2,我正在编写一个 json 解析器,而 IntelliJ 建议对我的语法进行此修复。

我不明白这是什么意思

对我来说,这个(Person.apply, _) 应该写成(Person.apply _),但是这样我得到一个cannot resolve symbol apply 并且代码无法编译。

既然我有一个重载的构造函数,(Person.apply _) 不应该用来自valuereads 函数的参数调用它吗?

package models

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class Person(id: Long = 0, name: String, age: Int){
  def this(name: String, age: Int) = this(0, name, age)
}

object Person {

  implicit val personFormat = Json.format[Person]

  implicit val valuereads = (__ \ "value").read {(
  (__ \ "name").read[String] and
  (__ \ "age").read[Int]
   )(Person.apply, _)   //**<=== THIS, what apply, _ stands for**

  def apply(name: String, age: Int) = new Person(name, age)
}

固定语法仍然无法编译,但我没有收到任何警告。我在这里做错了什么?

顺便说一句,我正在关注此信息:https://www.playframework.com/documentation/2.4.x/ScalaJsonCombinators

【问题讨论】:

    标签: scala intellij-idea playframework playframework-2.0


    【解决方案1】:

    你在这里遗漏了一些东西。对于初学者来说,虽然允许在案例类中使用备用构造函数,但通常认为最好的做法是避免 Scala 中的方法重载(请参阅此处的讨论 Why "avoid method overloading"?)。如果你想提供一个“智能构造函数”,你可以在Person伴生对象中放置一个,像这样:

    object Person {
      def makePerson(name: String, age: Int) = Person(name = name, age = age)
    }
    

    请注意,我没有使用 new 关键字,该关键字只能用于普通的旧 classes。您也可以像您所做的那样在伴随对象中使用apply,但是您会在这里遇到歧义,Reads 实例不确定您是指伴随对象还是案例类本身.

    另外,请注意,您在案例类中的替代构造函数实际上所做的只是您的默认参数已经完成的工作。如果您只是将带有默认参数的参数放在最后一个位置,如下所示:

    case class Person(name: String, age: Int, id: Long = 0)
    

    那你就可以了

    Person("bob", 25) 
    

    构造一个Person,id 将使用 0。

    【讨论】:

    • 使用 case class Person 免费为您提供伴随对象。如果你定义object Person,你是否松散了copyapply之类的方法,因此你需要重新定义它们(如果需要)...?
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 2011-11-13
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多