0 scala list append object cumulative-sum
据说我有以下内容
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]
Run Code Online (Sandbox Code Playgroud)
我不明白其中的区别。我想使用它的原因是我想要一个运行列表,其中元素将有条件地添加到循环中。所以在这种情况下,total最初应该是一个接受test对象的空列表。我该怎么做呢?
任何反馈表示赞赏!
让我首先解释一些关于 Scala 的基础知识。
在 Scala 中,您定义一个类,如下所示,
scala> class Demo(a: String, b: Int) {
| def stringify: String = a + " :: " + b
| }
// defined class Demo
Run Code Online (Sandbox Code Playgroud)
您可以将 aclass视为提供给 Scala 的蓝图,它将用于创建 that 的实例class。在这里, 的每个实例class Demo都有两个属性——a它们是 a String,b哪个是 anInt和一个方法——stringify它们将返回 a String。
scala> val demo1 = new Demo("demo1", 1)
// demo1: Demo = Demo@21eee94f
scala> demo1.getClass
// res0: Class[_ <: Demo] = class Demo
Run Code Online (Sandbox Code Playgroud)
这demo1是class Demo和 has 的一个实例type Demo。
Scala 也有一个概念,object即专门生成的内部类的实例。
scala> object OtherDemo {
| val a: Int = 10
| }
// defined object OtherDemo
scala> DemoObject.getClass
// res2: Class[_ <: OtherDemo.type] = class OtherDemo$
Run Code Online (Sandbox Code Playgroud)
这里OtherDemo将是那个特别生成的唯一实例,class OtherDemo$并且具有type OtherDemo.type.
然后case class在 Scala 中有
scala> case class AnotherDemo(a: Int)
// defined class AnotherDemo
Run Code Online (Sandbox Code Playgroud)
这不仅会创建一个,class AnotherDemo而且还会创建一个object AnotherDemo我们称之为伴随对象的对象。这相当于,
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
}
Run Code Online (Sandbox Code Playgroud)
我们把这个object AnotherDemo作为companion object的class AnotherDemo。
我们可以通过AnotherDemo两种方式创建实例,
// 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$
Run Code Online (Sandbox Code Playgroud)
此外,在 Scala 中,您的类名应以大写字母开头。这使您可以轻松地将它们与应以小写字母开头的实例变量区分开来。这有助于您避免混淆。
现在,它应该是a: String而不是a: string。
scala> case class Test(
| a: String,
| b: String,
| c: Int,
| d: Int
| )
// defined class Test
Run Code Online (Sandbox Code Playgroud)
现在,当你写作时,
scala> var temp = List(Test("lol","lel",1,2))
// temp: List[Test] = List(Test(lol,lel,1,2))
Run Code Online (Sandbox Code Playgroud)
它实际上相当于,
var temp = List.apply(Test.apply("lol","lel",1,2))
Run Code Online (Sandbox Code Playgroud)
或者,
val test1 = Test.apply("lol","lel",1,2)
var temp = List.apply(test1)
Run Code Online (Sandbox Code Playgroud)
在Test在Test.apply是不是你的class Test,但companion object Test。并调用Test.apply返回的实例class Test ,其被传递到List.apply最终得到List的type List[Test]含有这种情况Test。
但是当你写这个的时候
scala> var total = List(Test)
// total: List[Test.type] = List(Test)
Run Code Online (Sandbox Code Playgroud)
您正在创建一个List类List[Test.type]包含companion object的Test。
专注于total: List[Test.type]一部分......这意味着,total是variable的type List[Test.type],这意味着它会想点到value/instance的type List[Test.type],并拒绝点别的。
现在......你正在尝试这样做,
total = total ::: temp
Run Code Online (Sandbox Code Playgroud)
这相当于,
val x = total ::: temp
total = x
Run Code Online (Sandbox Code Playgroud)
实际上,
val x = temp.:::(total)
total = x
Run Code Online (Sandbox Code Playgroud)
现在看看这个val x = total ::: temp,
scala> val x = total ::: temp
// x: List[Serializable] = List(Test, Test(lol,lel,1,2))
Run Code Online (Sandbox Code Playgroud)
你看……这x是类型List[Serializable]。所以当你尝试时total = x,你会得到以下错误,
scala> total = x
// <console>:13: error: type mismatch;
// found : List[Serializable]
// required: List[Test.type]
// total = x
// ^
Run Code Online (Sandbox Code Playgroud)
这意味着total需要 aList[Test.type]但你给它一个List[Serializable].