是否可以在scala中的额外构造函数中调用构造函数之前添加功能?
让我们说,我有类User,并希望得到一个字符串 - 并将其拆分为属性 - 将它们发送给构造函数:
class User(val name: String, val age: Int){
def this(line: String) = {
val attrs = line.split(",") //This line is leading an error - what can I do instead
this(attrs(0), attrs(1).toInt)
}
}
所以我知道在发送之前我无法添加一行,因为所有构造函数都需要调用另一个构造函数作为构造函数的第一个语句。
那我该怎么做呢?
编辑:
我有很长的属性列表,所以我不想重复line.split(",")
答案 0 :(得分:2)
丑陋,但工作解决方案#1:
class User(val name: String, val age: Int){
def this(line: String) = {
this(line.split(",")(0), line.split(",")(1).toInt)
}
}
丑陋,但工作解决方案#2:
class User(val name: String, val age: Int)
object User {
def fromString(line: String) = {
val attrs = line.split(",")
new User(attrs(0), attrs(1).toInt)
}
}
可以用作:
val johny = User.fromString("johny,35")
您可以使用apply
代替fromString
,但这会导致混淆(在一种情况下您必须使用new
,在另一种情况下您必须放弃它)所以我更喜欢使用不同的名称
答案 1 :(得分:2)
我认为这是一个让伴侣对象和apply()
方法很好地发挥作用的地方:
object User {
def apply(line: String): User = {
val attrs = line.split(",")
new User(attrs(0), attrs(1).toInt)
}
}
class User(val name: String, val age: Int)
然后您只需按以下方式创建对象:
val u1 = User("Zorro,33")
此外,既然您无论如何都要公开name
和age
,您可以考虑使用案例类而不是标准类,并且可以采用一致的方式构建User
个对象(不使用{{ 1}}关键字):
new
答案 2 :(得分:1)
另一个丑陋的解决方案:
class User(line: String) {
def this(name: String, age: Int) = this(s"$name,$age")
val (name, age) = {
val Array(nameStr,ageStr) = line.split(",")
(nameStr,ageStr.toInt)
}
}
但是使用伴侣对象的方法可能更好。