2012-04-03 19 views
0

Scalaのコンストラクタの読み込みに問題があります。私はオーバーロードされたCTORの値を渡すためにしようとするたびに、私は問題ScalaのCTORのオーバーロード

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

Unspecified value parameter clientList.  

エラーを取得するには、私の目標は、2つの異なるデータ型を使用して作成されたオブジェクトを持つことです。 1つはNodeSeq、もう1つはリストです。両方とも決してない。私は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 
    } 

} 
+4

Scalaコードで 'null'を使用しないでください。実際には、Javaとの相互運用性のためにのみ存在します。代わりに 'Option'を使用してください。 (申し訳ありませんが、誰かが 'null 'を使っているのを見るたびにこれを言わなければなりません...)。 – Jesper

答えて

5

作業コードを送信していません。未定義のvarsを持つことはできません。

とにかく、コンストラクタをオーバーライドしても、ではなく、がコンパニオンオブジェクト内のビルダーをオーバーライドするという問題があります。これを追加し、それはあなたが望むように動作します:

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 
    /* ... */ 
} 

とそれを解析するために、各方法のために1回、2回、それを継承する:あなたがしたいデータが含まれている特色定義する必要があり

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

をしたり、リストにNodeSeqを回すことができるし、それを解析するか、または他のさまざまなことを行います。この方法では、おそらく後で変更するつもりはないバルスの束を公開しないようにします。

+0

スカラーはC#にあるので、カーはスケートになります。誰もがマルチアプリケーションを適用できるかどうか分かりませんでしたが、常にこの言語で新しい何かがあります;-) – virtualeyes

+0

@virtualeyes - 私はDanial C. Sobralに名誉を与えていると思います。 –

+0

確かに彼はS.O.明らかに、Scalaの「ロックスター」がここに掲載されていますが、ダニエルは確かにそれらの1つです。 Skeetの参考文献は知識だけではなく、学生が「a-ha、今すぐ入手する」という質の高い回答です。 @Oxbow湖もかなり良いです。とにかく、S.O.それ自体はネット上の単一の最高の教育/学習リソースです。私は卒業しましたが、私はまだ学校にいます;-) – virtualeyes

0

補助コンストラクタは単純な1ライナ用であり、この場合は適切ではありません。より多くの慣用的な方法は、コンパニオンオブジェクトにファクトリメソッドを定義するには、次のようになります。

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

私はまた、可変性を排除し、それは一般的に、より安全に実行することによって、あなたのコードを改良する自由を取りました。

関連する問題