包含列表的Scala类

时间:2018-11-24 10:45:58

标签: scala list class

我有一个非常基本和简单的Scala问题。例如,我有一个类似的Java类

class Dataset{
   private List<Record> records;
   Dataset(){
       records = new ArrayList<Record>()
   }
   public void addItem(Record r){
       records.add(r)


      }
}

当我尝试在Scala中编写相同的类时,我陷入了一些错误:

class RecordSet() {

  private var dataset:List[Record]
  def this(){
    dataset = new List[Record]
  }

  def addRecord(rd: Record)={
    dataset :+ rd
  }

}

我无法声明类似(私有var数据集:List [Record])的List变量 并且无法编写默认的构造函数。

2 个答案:

答案 0 :(得分:2)

这是如何复制问题中提到的Java代码:

// defining Record so the code below compiles
case class Record() 

// Here is the Scala implementation
class RecordSet(private var dataset:List[Record]) {
    def addRecord(rd: Record)={
      dataset :+ rd
    }
  }

一些解释:

在Scala中,定义类时,可以将参数传递给类定义。例如:class Foo(num:Int, descr:String) Scala会自动使用给定的参数为您创建一个主构造函数。因此,您现在可以像new Foo(1, "One")一样实例化Foo。在Java中,您必须显式定义参数接受构造函数。

您必须知道,传递的参数不会自动成为该类的实例成员。尽管可以,但是可以告诉Scala将其设为实例成员。有多种方法可以执行此操作,一种方法是在参数前面加上varval。例如class Foo(val num:Int, val descr:String)class Foo(var num:Int, var descr:String)。区别在于使用val时,实例变量是不可变的。使用var,它们是可变的。

此外,默认情况下,Scala将生成的实例成员将是公共的。这意味着可以直接从对象的实例访问它们。例如:

val foo = new Foo(1, "One")
println(foo.num) // prints 1.

如果希望它们是私有的,则可以在定义中添加private关键字。这样就变成了:

class Foo(private var num:Int, private var desc:String)

代码无法编译的原因是您定义了一个名为this()的方法,该方法用于创建多个构造函数。 (而不是创建一个初始化私有字段的构造函数,这是根据您共享的Java代码判断的意图)。您可以在Google上搜索多个构造函数或辅助构造函数,以了解有关此内容的更多信息。

答案 1 :(得分:1)

  1. 就像爸爸告诉您的代码中的问题一样,实际上您使用this关键字创建了auxilary构造函数,该构造函数具有一些限制,例如the first line of your auxilary constructor must be another constructor (auxilary/primary)。因此,您不能使用这种方法来创建类。

    1. 此外,您不能在scala具体类private var dataset:List[Record]中编写这样的行,因为它被视为抽象类(未提供定义)。

现在输入代码。通常在Scala中,我们不喜欢可变性,因为它在我们的函数中引入了副作用(这不是功能性的方式,但是由于scala并非纯粹是功能性的,因此您也可以使用可变性。)

以Scala方式,代码应如下所示:

  class RecordSet(private val dataset:List[Record]) {
    def addRecord(rd: Record): RecordSet ={
      new RecordSet(dataset :+ rd)
    }
  }

现在,上述类别中没有可变性。每当将元素添加到数据集时,都会创建一个RecordSet的新实例。因此没有可变性。

但是,如果您必须在应用程序中使用相同的类引用,请对数据集使用可变集合,如下所示:

  class RecordSet(private val dataset:ListBuffer[Record]) {

    def addRecord(rd: Record): ListBuffer[Record] ={
      dataset += rd
    }
  }

以上代码将新记录添加到具有相同类引用的现有数据集中。