2017-12-07 10 views
0

たぶん私は発現は

case class test { 
        a:string 
        b: string 
        c: Int 
        d: Int } 


var temp = List(test("lol","lel",1,2)) 
var total = List(test) 

total = total:::temp //this doesn't work because temp is of type [test] while total is of type [test.type] 

私は違いを理解していないが、次のしている期待のリストスカラ座に準拠していません。 私はこれを使用したい理由は、要素がループ内で条件付きで追加される実行リストを作成したいということです。 この場合、totalは最初にtest個のオブジェクトをとる空のリストでなければなりません。これはどうすればいいですか?

フィードバックは高く評価されています。

答えて

1

まず、Scalaについての基本的なことを説明します。 Scalaで

、あなたはそのclassのインスタンスを作成するために使用されるスカラ座に与えられた青写真としてclassと考えることができ

scala> class Demo(a: String, b: Int) { 
| def stringify: String = a + " :: " + b 
| } 
// defined class Demo 

、次のようなクラスを定義します。ここでは、class Demoのすべてのインスタンスは、Stringbとなる2つのプロパティ-Intと1つのメソッド-を持ち、Stringを返します。ここ

scala> val demo1 = new Demo("demo1", 1) 
// demo1: Demo = [email protected] 

scala> demo1.getClass 
// res0: Class[_ <: Demo] = class Demo 

demo1classDemoのインスタンスであり、typeDemoを有しています。

また、Scalaには特別に生成された内部クラスのインスタンスであるobjectという概念があります。

ここ
scala> object OtherDemo { 
| val a: Int = 10 
| } 
// defined object OtherDemo 

scala> DemoObject.getClass 
// res2: Class[_ <: OtherDemo.type] = class OtherDemo$ 
OtherDemo

は、特別に生成classOtherDemo$の唯一のインスタンスであるとtypeOtherDemo.typeを有しているであろう。

そしてcase classこれはclassAnotherDemoだけでなく、我々はコンパニオンオブジェクトを呼び出すobjectAnotherDemoないだけに作成されますScalaの

scala> case class AnotherDemo(a: Int) 
// defined class AnotherDemo 

です。これは私たちがclassAnotherDemocompanion objectとしてこのobjectAnotherDemoを呼び出す

class AnotherDemo(a: Int) 

object AnotherDemo { 

    def apply(a: Int): AnotherDemo = new AnotherDemo(a) 

    def unapply(anotherDemo: AnotherDemo): Option[Int] = Some(anotherDemo.a) 

    // And many more utility functions 
} 

、と等価です。

私たちはスカラ座では、あなたのクラス名は大文字で始まる必要があり、二つの方法、また

// By using new keyword, as we can do for any class 
scala> val anotherDemo1 = new AnotherDemo(1) 
// anotherDemo1: AnotherDemo = AnotherDemo(1) 

// Or we can use `apply` method provided by companion object 
scala> val anotherDemo2 = AnotherDemo(2) 
// anotherDemo2: AnotherDemo = AnotherDemo(2) 

scala> anotherDemo1.getClass 
// res6: Class[_ <: AnotherDemo] = class AnotherDemo 

scala> anotherDemo2.getClass 
// res7: Class[_ <: AnotherDemo] = class AnotherDemo 

scala> AnotherDemo.getClass 
// res8: Class[_ <: AnotherDemo.type] = class AnotherDemo$ 

AnotherDemoのインスタンスを作成することができます。これにより、小文字で始まるインスタンス変数と簡単に区別することができます。これは混乱を避けるのに役立ちます。

ここでa: Stringであり、a: stringではないとします。

scala> case class Test(
|  a: String, 
|  b: String, 
|  c: Int, 
|  d: Int 
| ) 
// defined class Test 

さて、あなたが書いたときに、

scala> var temp = List(Test("lol","lel",1,2)) 
// temp: List[Test] = List(Test(lol,lel,1,2)) 

それは実際に相当し、

var temp = List.apply(Test.apply("lol","lel",1,2)) 

あるいは、

val test1 = Test.apply("lol","lel",1,2) 
var temp = List.apply(test1) 

Test.applyTestがヨーヨーではありませんur class Testでも、companion object Testです。そしてTest.applyを呼び出すと、最終的ListTestのこのインスタンスを含むList[Test]typeのを取得するためにList.applyに渡されるclass Testのインスタンスを返します。

しかし、ときにこれを書き、

scala> var total = List(Test) 
// total: List[Test.type] = List(Test) 

あなたはTestcompanion objectを含むタイプList[Test.type]Listを作成しています。 total: List[Test.type]一部の

フォーカス...これはtotalは、それがtypeList[Test.type]value/instanceを指すようになるでしょうし、何か他のものを指すように拒否することを意味しますtypeList[Test.type]variableであることを意味します。

今...あなたはこれをやろうとしている、と等価である

total = total ::: temp 

、実際には

val x = total ::: temp 
total = x 

val x = temp.:::(total) 
total = x 

は今、このval x = total ::: tempを見て、

scala> val x = total ::: temp 
// x: List[Serializable] = List(Test, Test(lol,lel,1,2)) 

ご覧ください... xList[Serializable]です。あなたがtotal = xをしようとするので、あなたは、エラー以下のtotalList[Test.type]を必要ですが、あなたはそれをList[Serializable]を与えていることを意味

scala> total = x 
// <console>:13: error: type mismatch; 
// found : List[Serializable] 
// required: List[Test.type] 
//  total = x 
//    ^

を取得します。

0

List(test)ではなく、total = List.empty[test]を探しています。 前者はタイプList[test]の空のリストを作成し、後者はタイプList[test.type]test.typetestと同じではなく、testのインスタンスのタイプを表す独自のオブジェクトです)の1要素リストです。

また、varを使用しないでください。彼らは邪悪であり、ユースケースの99%でスカラーでは本当に必要ではありません。他の1%を自信を持って区別できるようにするには、その言語で十分なグリップを得るまで、そのキーワードがまったく存在しないふりをしてください。

0

あなたがこれを行うときは:あなたは、オブジェクトのテストを初期化していない

var total = List(test)

を、それはリストのタイプがTest.typeである理由、あなただけのオブジェクトのテンプレートのリストを作成しています。

あなたの代わりにこれを行うとき: var temp = List(test("lol","lel",1,2))

をヨテンプレート(この場合はクラス、テスト)からインスタンス化されたオブジェクトを持っているので、一時のタイプはList[Temp]です。

だからあなたのような何かをした場合、:

val template = Test はその後トンのタイプはTest.type

であり、あなたは、このようにtemplateからオブジェクトのテストをインスタンス化することができます

val instantiated = template("lol","lel",1,2)

あなたの例で見てきたように、変数totalはインスタンス化できるテンプレートのリストに過ぎません変数はtempの変数はTestのオブジェクトのリストです。

val t: List[Test] = List.empty

次にあなたが

0

あなたに基づいて、このリストに(タイプTestの)任意のオブジェクトを追加することができます:あなたがちょうどしなければならないタイプのテストのオブジェクトの空のリストを作成するには

(私は、要素がループ内で条件付きで追加される実行リストを持っていたい)、私の理解は、ある種のソースからTestオブジェクトを取得していて、それらが特定の基準を満たす場合にのみリストに入れたいということです。この要件をメソッドとして表現できます。便宜上、メソッドをTestのコンパニオンオブジェクトに配置します。コンパニオンオブジェクトは、オブジェクトをインスタンス化することなく利用可能なものを配置する場所です。

case class Test(a: String, b: String, c: Int, d: Int) 

object Test { 
    /** 
    Returns a list of `Test` objects that pass the given criteria. 

    @param tests some source of tests that we can loop over one at a 
    time. 
    @param condition checks whether a `Test` object should go into our 
    output list. 
    */ 
    def runningList(
    tests: Iterable[Test])(condition: Test => Boolean): List[Test] = 
    tests.filter(condition).toList 
} 

あなたは(例えば)のようにそれを使用することができます:

Test.runningList(testsSource) { test => test.c > 0 && test.d < 100 } 

あなたがここに見ることができるように、私はイテラブルとそのリスト変換方法、マルチPARAMETER-ようないくつかのScalaの機能を、使用してきましたリストメソッド、ファーストクラス関数、last-argument DSLとしての関数などがあります。これらのトピックに関するご質問がある場合は、Scalaチュートリアルをお勧めします。

関連する問題