Scala 问题重载CTOR';在斯卡拉

Scala 问题重载CTOR';在斯卡拉,scala,constructor,overloading,Scala,Constructor,Overloading,我在Scala中加载构造函数时遇到了一个问题。每次我尝试传递一个重载的CTOR值时,我都会得到错误 Example: var client : Client = Client(*variable type List[String]()*); Unspecified value parameter clientList. 我的目标是使用两种不同的数据类型创建一个对象。一个是NodeSeq,另一个是列表。决不能两者兼而有之。我是否正确地过度加载了CTOR,或者是否有更有效的方

我在Scala中加载构造函数时遇到了一个问题。每次我尝试传递一个重载的CTOR值时,我都会得到错误

Example: 
    var client : Client = Client(*variable type List[String]()*);

 Unspecified value parameter clientList.    
我的目标是使用两种不同的数据类型创建一个对象。一个是NodeSeq,另一个是列表。决不能两者兼而有之。我是否正确地过度加载了CTOR,或者是否有更有效的方法来实现我的目标

package api
import xml._

case class Client(clientNode: NodeSeq, clientList: List[String]) {

  def this(clientNode: NodeSeq) = this(clientNode, null)
  def this(clientList: List[String]) = this(null, clientList)

  var firstName: String
  var lastName: String
  var phone: String
  var street: String
  var city: String
  var state: String
  var zip: String
  var products = List[String]()
  var serviceOrders = List[String]()

  if (clientList == null) {
    firstName = (clientNode \\ "firstname").text
    lastName = (clientNode \\ "lastname").text
    phone = (clientNode \\ "phone").text
    street = (clientNode \\ "street").text
    city = (clientNode \\ "city").text
    state = (clientNode \\ "state").text
    zip = (clientNode \\ "zip").text

    (clientNode \\ "products").foreach(i => products = i.text :: products)

    (clientNode \\ "serviceOrders").foreach(i => serviceOrders = i.text :: serviceOrders)

  } else {
    firstName = clientList(0)
    lastName = clientList(1)
    phone = clientList(2)
    street = clientList(3)
    city = clientList(4)
    state = clientList(5)
    zip = clientList(6)
  }

  override def toString(): String = {
    return "Name : " + firstName + " " + lastName +
      "\nAddress : " +
      "\n\t" + street +
      "\n\t" + city + ", " + state + " " + zip
  }

}

您没有发布工作代码;不能有未定义的变量

无论如何,问题是,即使您已经重写了构造函数,也没有重写伴随对象中的构造函数。添加此项,它将按您想要的方式工作:

object Client {
  def apply(clientNode: NodeSeq) = new Client(clientNode)
  def apply(clientList: List[String]) = new Client(clientList)
}
trait ClientData {
  def firstName: String
  def lastName: String
  /* ... */
}
(如果您正在使用REPL,请确保使用
:paste
将其与case类一起输入,以便添加到默认的伴随对象,而不是替换它)

但更深层次的问题是,这不是解决问题的方式。您应该定义一个包含所需数据的特征:

object Client {
  def apply(clientNode: NodeSeq) = new Client(clientNode)
  def apply(clientList: List[String]) = new Client(clientList)
}
trait ClientData {
  def firstName: String
  def lastName: String
  /* ... */
}
并从中继承两次,每种解析方式一次:

class ClientFromList(cl: List[String]) extends ClientData {
  val firstName = cl.head
  . . .
}

或者,您可以将NodeSeq转换为一个列表,并在那里解析它,或者进行其他各种操作。这样可以避免暴露一堆可能以后不会更改的变量。

您没有发布工作代码;不能有未定义的变量

无论如何,问题是,即使您已经重写了构造函数,也没有重写伴随对象中的构造函数。添加此项,它将按您想要的方式工作:

object Client {
  def apply(clientNode: NodeSeq) = new Client(clientNode)
  def apply(clientList: List[String]) = new Client(clientList)
}
trait ClientData {
  def firstName: String
  def lastName: String
  /* ... */
}
(如果您正在使用REPL,请确保使用
:paste
将其与case类一起输入,以便添加到默认的伴随对象,而不是替换它)

但更深层次的问题是,这不是解决问题的方式。您应该定义一个包含所需数据的特征:

object Client {
  def apply(clientNode: NodeSeq) = new Client(clientNode)
  def apply(clientList: List[String]) = new Client(clientList)
}
trait ClientData {
  def firstName: String
  def lastName: String
  /* ... */
}
并从中继承两次,每种解析方式一次:

class ClientFromList(cl: List[String]) extends ClientData {
  val firstName = cl.head
  . . .
}

或者,您可以将NodeSeq转换为一个列表,并在那里解析它,或者进行其他各种操作。这样可以避免暴露一堆可能以后不会更改的变量。

辅助构造函数用于简单的单行程序,不适用于这种情况。更惯用的方法是在伴随对象中定义工厂方法:

case class Client(firstName: String,
                  lastName: String,
                  products: List[String] = Nil)

object Client {

  import scala.xml.NodeSeq

  def fromList(list: List[String]): Option[Client] =
    list match {
      case List(firstName, lastName) =>
        Some(Client(firstName, lastName))
      case _ => None
    }

  def fromXml(nodeSeq: NodeSeq): Option[Client] = {
    def option(label: String) =
      (nodeSeq \\ label).headOption.map(_.text)
    def listOption(label: String) =
      (nodeSeq \\ label).headOption.map {
        _.map(_.text).toList
      }
    for {
      firstName <- option("firstname")
      lastName <- option("lastname")
      products <- listOption("products")
    } yield Client(firstName, lastName, products)
  }
}
case类客户端(名字:String,
姓氏:String,
产品:列表[字符串]=Nil)
对象客户端{
导入scala.xml.NodeSeq
def fromList(列表:列表[字符串]):选项[客户端]=
列表匹配{
病例列表(名字、姓氏)=>
一些(客户(姓、名))
案例=>无
}
def fromXml(nodeSeq:nodeSeq):选项[Client]={
def选项(标签:字符串)=
(nodeSeq\\label).headOption.map(\uq.text)
def列表选项(标签:字符串)=
(nodeSeq\\label).headOption.map{
_.map(u.text).toList
}
为了{

firstName辅助构造函数用于简单的单行程序,不适用于这种情况。更惯用的方法是在伴随对象中定义工厂方法:

case class Client(firstName: String,
                  lastName: String,
                  products: List[String] = Nil)

object Client {

  import scala.xml.NodeSeq

  def fromList(list: List[String]): Option[Client] =
    list match {
      case List(firstName, lastName) =>
        Some(Client(firstName, lastName))
      case _ => None
    }

  def fromXml(nodeSeq: NodeSeq): Option[Client] = {
    def option(label: String) =
      (nodeSeq \\ label).headOption.map(_.text)
    def listOption(label: String) =
      (nodeSeq \\ label).headOption.map {
        _.map(_.text).toList
      }
    for {
      firstName <- option("firstname")
      lastName <- option("lastname")
      products <- listOption("products")
    } yield Client(firstName, lastName, products)
  }
}
case类客户端(名字:String,
姓氏:String,
产品:列表[字符串]=Nil)
对象客户端{
导入scala.xml.NodeSeq
def fromList(列表:列表[字符串]):选项[客户端]=
列表匹配{
病例列表(名字、姓氏)=>
一些(客户(姓、名))
案例=>无
}
def fromXml(nodeSeq:nodeSeq):选项[Client]={
def选项(标签:字符串)=
(nodeSeq\\label).headOption.map(\uq.text)
def列表选项(标签:字符串)=
(nodeSeq\\label).headOption.map{
_.map(u.text).toList
}
为了{

firstName在Scala代码中不使用
null
。它实际上只存在于与Java的互操作性中。请改用
选项
。(对不起,每次我看到有人使用
null
,我都不得不这么说。)。不要在Scala代码中使用
null
。它实际上只存在于与Java的互操作性中。请改用
Option
。(对不起,每次我看到有人使用
null
,我都必须这么说。)Kerr对双向飞碟就像Scala对C#一样。不知道一个人可以多重应用,在这门语言中总是有新的东西;-)@virtualeyes-我认为这个荣誉实际上属于Danial C.Sobral。当然,但他在s.O.上的时间比你长一年;-)显然Scala有几个“摇滚明星”在这里发帖,丹尼尔肯定是其中之一;双向飞碟的参考不仅是知识,而且是答案的质量,学生会说,“哈哈,现在我明白了!”@Oxbow Lakes也很不错。不管怎样,S.O.本身就是网络上最好的教学资源;虽然我已经毕业,但我还在上学;-)Kerr对Skeet就像Scala对C#一样。不知道一个人可以多种应用,在这门语言中总是有些新的东西;-)@virtualeyes-我认为这个荣誉实际上属于Danial C.Sobral。当然,但是他在s.O.上的时间比你长了一年;-)显然这里有一些Scala“摇滚明星”的帖子,丹尼尔肯定是其中之一;双向飞碟的参考不仅是知识,而且是答案的质量,学生会说,“哈哈,现在我明白了!”@Oxbow Lakes也不错。无论如何,S.O.本身就是网上最好的教学资源;虽然我已经毕业了,但我还在上学;-)