Scala 问题重载CTOR';在斯卡拉
我在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,或者是否有更有效的方
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.本身就是网上最好的教学资源;虽然我已经毕业了,但我还在上学;-)