类型列表(对象)的表达式不符合预期的列表标量

时间:2017-12-07 12:21:59

标签: scala list object append running-total

据说我有以下

total

我不明白其中的区别。 我想要使​​用它的原因是我希望有一个运行列表,其中元素将在循环中有条件地添加。 所以在这种情况下,test最初应该是一个空的列表,它带有Datapump = pd.merge(hack, health, how='inner', left_on=['Date', 'CP'], right_on=['Creation', 'cp']) 个对象。我该怎么做?

感谢任何反馈!

4 个答案:

答案 0 :(得分:2)

首先,我将解释一些关于Scala的基础知识。

在Scala中,您可以定义类如下的类

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

您可以将class视为给予Scala的蓝图,该蓝图将用于创建class的实例。在此,class Demo的每个实例都有两个属性 - a,它们是Stringb将是Int,一个方法 - {{ 1}}将返回stringify

String

此处scala> val demo1 = new Demo("demo1", 1) // demo1: Demo = Demo@21eee94f scala> demo1.getClass // res0: Class[_ <: Demo] = class Demo demo1 class的一个实例,并且Demo type

Scala还有Demo的概念,它是特殊生成的内部类的实例。

object

此处scala> object OtherDemo { | val a: Int = 10 | } // defined object OtherDemo scala> DemoObject.getClass // res2: Class[_ <: OtherDemo.type] = class OtherDemo$ 将是特别生成的OtherDemo classOtherDemo$ type的唯一实例。

然后Scala中有OtherDemo.type

case class

这不仅会创建scala> case class AnotherDemo(a: Int) // defined class AnotherDemo 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 } object称为AnotherDemo companion object的{​​{1}}。

我们可以通过两种方式创建class的实例,

AnotherDemo

此外,在Scala中,您的班级名称应以大写字母开头。这使您可以轻松地将它们与应该以小写字母开头的实例变量区分开来。这可以帮助您避免混淆。

现在,它应该是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$

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,而是Test.apply。并且调用class Test会返回companion object Test的实例,该实例将传递给Test.apply,最终获得包含此实例的class Test List.applyList type

但是当你写这个时,

List[Test]

您正在创建Test类型scala> var total = List(Test) // total: List[Test.type] = List(Test) ,其中包含List List[Test.type] {/ 1}}。

关注companion object部分......这意味着Testtotal: List[Test.type] total的{​​{1}},这意味着它会指向variable type的{​​{1}},并拒绝指出任何其他内容。

现在......你正试图这样做,

List[Test.type]

相当于,

value/instance

实际上是

type

现在看看这个List[Test.type]

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

这意味着x需要List[Serializable],但您提供了total = x

答案 1 :(得分:0)

您正在寻找total = List.empty[test]而不是List(test)。 前者创建一个类型为List[test]的空列表,后者是类型List[test.type]的单元素列表(test.typetest不同 - 它是它自己的object,表示test)的实例类型。

另外,请勿使用var。它们是邪恶的,并且在99%的用例中并不是真正需要scala。只是假装关键字根本不存在,直到你掌握了足够的语言能够自信地区分其他1%。

答案 2 :(得分:0)

执行此操作时:

var total = List(test)

您没有初始化对象测试,这就是列表类型为Test.type的原因,您只是为对象创建模板列表。

当你这样做时: var temp = List(test("lol","lel",1,2))

哟让对象从模板(一个类,在本例中为Test)中实例化,因此temp的类型为List[Temp]

所以,如果你做了类似的事情:

val template = Test 那么t的类型是Test.type

你可以像这样template实例化一个对象Test:

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

正如您在示例中所看到的,total变量只是一个模板列表,您可以在其中实例化对象,而temp变量是Test类型的对象列表。

要创建Test类型的空对象列表,您只需执行以下操作:

val t: List[Test] = List.empty

然后您可以将任何对象(类型Test)添加到此列表

答案 3 :(得分:0)

根据您的说明(&#39;我希望有一个运行列表,其中元素将有条件地添加到循环中),我的理解是您从某些来源获取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 }

正如您在这里看到的,我使用了一些Scala功能,例如iterables及其列表转换方法,多参数列表方法,一流函数,函数作为最后一个参数DSL,以及等等。如果您对这些主题有更多疑问,我建议您使用Scala教程。