Scala类:在创建新实例时避免参数

时间:2016-11-25 18:23:02

标签: scala class

假设我有2个文件。

  • myMainApplication.scala
  • printInfos.scala

简单地说myMainApplication.scala包含

val name = "blah"
val age= 45

简单地说,我的类myMainApplication.scala应该通过创建一个新的printInfos实例来打印出名称和年龄。但是,我不应该在创建实例时添加任何参数。

我想避免的事情:

内部printInfos.scala

    class printInfos(val myName: String, 
                     val myAge: Int
                     val myLoc: String
                     val myNPP: Double
                     val myCountry: String
                     val myProvice: String
                     val myNPAP: String) {

    def printInfos() = {
        println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvice + myNPAP)
    }

}

在myMainApplication.scala内部

val name = "blah"
val age= 45
val loc = "blah"
val npp = 45.5
val country = "germany"
val province = "bayern"
val npap = "blaha"
// want to avoid to enter so many params
val printInfoInstance = new printInfos(name, age, loc, npp, country, province, npap)
printInfoInstance.printInfos()

我想得到类似的东西:

内部printInfos.scala

    class printInfos() {

       var myName: String  = 0
       var myAge: Int  = 0
       var myLoc: String  = 0
       var myNPP: Double  = 0
       var myCountry: String  = 0
       var myProvice: String  = 0
       var myNPAP: String  = 0

    def printInfos() = {
        println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvice + myNPAP)
    }

}

在myMainApplication.scala内部

// want to create new instance with no params at begining
val printInfoInstance = new printInfos()

val name = "blah"
printInfoInstance.myName() = name
val age= 45
printInfoInstance.myAge() = age
val loc = "blah"
printInfoInstance.myLoc() = loc
val npp = 45.5
printInfoInstance.myNPP() = npp
val country = "germany"
printInfoInstance.myCountry() = country
val province = "bayern"
printInfoInstance.myProvice() = province
val npap = "blaha"
printInfoInstance.myNPAP() = npap

printInfoInstance.printInfos

寻求改进

是否可以获得类似于第二个提案的内容但避免使用var ?但是,最终目标仍然是在创建新的intance时避免添加大量参数

3 个答案:

答案 0 :(得分:3)

我建议你使用scala的case类。它提供了一种复制方法,允许您使用更改的参数创建新实例。这使一切都变得不可变。请注意,您不必更新所有参数 - 您可以一次只执行一个参数。

case class printInfos(myName: String = "",
                      myAge: Int = 0,
                      myLoc: String = "",
                      myNPP: Double = 0,
                      myCountry: String = "",
                      myProvince: String = "",
                      myNPAP: String = "") {
  def printInfos() = {
    println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvince + myNPAP)
  }
}

val printInfoInstance = new printInfos()

val name = "blah"
val age= 45
val loc = "blah"
val npp = 45.5
val country = "germany"
val province = "bayern"
val npap = "blaha"

val newInstance = printInfoInstance.copy(
  myName = name,
  myAge = age,
  myLoc = loc,
  myNPP = npp,
  myCountry = country,
  myProvince = province,
  myNPAP = npap
)

newInstance.printInfos()

答案 1 :(得分:1)

除了@longshorej所提到的,只要你定义了一个案例类。您可以在没有new关键字的情况下进行实例化: printInfos("name","age","loc","npp","country","province","npap")会创建一个新实例。

对于打印部分,我建议覆盖toString以使其与标准术语完全一致。

答案 2 :(得分:1)

类型系统的好处能够要求创建类的有效实例所需的所有参数。

如果你想避免每次都传递所有参数的详细程度,你可以为它们提供默认值(如果它们真的是可选的,那么只是一个好主意,因为你真的想避免无效的中间状态)。

// assuming it doesn't make sense to instantiate without 
// a few required parameters
case class InfoPrinter (
  name: String,             // required 
  age: Int,                 // required
  loc: String = "",
  NPP: Double = 0,
  country: String = "",
  province: String = "",
  NPAP: String = ""
) {
  def printInfos = 
    println(s"Your method printInfos print out $name $age $loc $NPP $country $province $NPAP")

}

然后您可以像这样使用它:

// named params or positionally
InfoPrinter("blah", 45, country="germany", province="bayern").printInfos

任何带默认值的参数都可以省略。