Проблемы перегрузки CTOR в Scala - PullRequest
0 голосов
/ 03 апреля 2012

У меня проблема с загрузкой конструкторов в Scala. Каждый раз, когда я пытаюсь передать значение для перегруженного CTOR, я получаю ошибку

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

 Unspecified value parameter clientList.    

Моя цель - создать объект, используя 2 разных типа данных. Один - 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
  }

}

Ответы [ 2 ]

5 голосов
/ 03 апреля 2012

Вы не опубликовали рабочий код; вы не можете иметь неопределенные переменные.

В любом случае, проблема в том, что даже если вы переопределили конструкторы, вы не переопределили компоновщики в объекте-компаньоне. Добавьте это, и все будет работать так, как вы хотите:

object Client {
  def apply(clientNode: NodeSeq) = new Client(clientNode)
  def apply(clientList: List[String]) = new Client(clientList)
}

(если вы используете REPL, обязательно введите :paste, чтобы ввести его вместе с классом дел, чтобы вы добавляли объект-компаньон по умолчанию вместо его замены).

Но более глубокая проблема заключается в том, что это не тот способ, которым вы должны решать проблему. Вы должны определить черту, которая содержит данные, которые вы хотите:

trait ClientData {
  def firstName: String
  def lastName: String
  /* ... */
}

и наследовать от него дважды, один раз для каждого способа его анализа:

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

или вы можете превратить NodeSeq в список и проанализировать его там, или другие разные вещи. Таким образом, вы избегаете показа множества переменных, которые, вероятно, не будут изменены позже.

0 голосов
/ 04 апреля 2012

Вспомогательные конструкторы предназначены для простых однострочников и в этом случае не подходят. Более идиоматическим способом было бы определить фабричные методы в сопутствующем объекте:

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)
  }
}

Я также взял на себя смелость улучшить ваш код, исключив изменчивость и сделав его в целом более безопасным во время выполнения.

...