主构造函数中的Scala局部变量

时间:2013-06-20 10:16:00

标签: scala scala-primary-constructor

如何在Scala中我可以在主构造函数中定义局部变量?

我需要从Scala for the impatient本书

解决这个问题
  

编写一个具有接受字符串的主构造函数的Person   包含第一个名称,空格和姓氏,例如new   人(“弗雷德史密斯”)。提供只读属性firstName和   姓。主构造函数参数应该是var,val还是   一个简单的参数?为什么呢?

目前我的解决方案如下:

class Person(firstLast: String) {
  private[this] val firstLastAsArr = firstLast.trim.split(" ")

  val firstName = firstLastAsArr (0)
  val lastName = firstLastAsArr (1)
}

如何限制firstLastAsArr变量可见性到主构造函数范围(现在它有类范围)?

5 个答案:

答案 0 :(得分:5)

一种解决方案是立即初始化firstNamelastName,从而允许将firstLastAsArr转换为初始化块内的本地临时值:

class Person(firstLast: String) {
  val (firstName, lastName) = {
    val firstLastAsArr = firstLast.trim.split(" ")
    (firstLastAsArr(0), firstLastAsArr(1))
  }
}

答案 1 :(得分:4)

这不是一般答案,但你可以用这种特殊方式写下:

  val Array(firstName, lastName) = firstLast.trim.split(" ")

答案 2 :(得分:2)

您不必严格需要中间变量:

class Person(firstLast: String) {
  val (firstName, lastName) =
    firstLast.trim.split(" ") match {case Array(first, last) => (first, last)}
}

但是,如果您从firstLast转换为firstNamelastName的转换时间会长一些,例如,因为您检查到的只有一个名字和一个姓氏,那么我将整个拆分业务封装在专用方法中:

class Person(firstLast: String) {
  val (firstName, lastName) = split(firstLast)

  private def split(firstLast: String): (String, String) = {
    val firstLastAsArr = firstLast.trim.split(" ")
    ...
    (first, last)
  }
}

答案 3 :(得分:1)

构造函数中的模式匹配工作正常,但您应该考虑将此类逻辑从构造函数移动到工厂方法:

case class Person(firstName: String, lastName: String)
object Person{
  def apply(firstLast: String) = {
    val firstLastAsArr = firstLast.trim.split(" ")
    new Person(firstLastAsArr(0), firstLastAsArr(1))
  }
}

val p = Person("My Title")

答案 4 :(得分:0)

<主构造函数中的模式匹配效果很好

  class Person(_fullName:String) {
    val (firstName, lastName) =  _fullName.split(" ") match {
      case Array(x:String, y:String, _*) => (x,y)
      case _ => (null,null)
    }
  }

请参阅我的github获取完整答案 https://github.com/BasileDuPlessis/scala-for-the-impatient/blob/master/src/main/scala/com/basile/scala/ch05/Ex07.scala