如何在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
变量可见性到主构造函数范围(现在它有类范围)?
答案 0 :(得分:5)
一种解决方案是立即初始化firstName
和lastName
,从而允许将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
转换为firstName
和lastName
的转换时间会长一些,例如,因为您检查到的只有一个名字和一个姓氏,那么我将整个拆分业务封装在专用方法中:
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