在Scala中,如果我创建一个这样的类:
class Time(var hour: Int) {
if (hour < 0) hour = 0
}
我可以轻松地使用创建一个新对象
x = new Time(4)
如果我需要花时间处理x
对象,我可以做
x.hour
我回来了res5: Int = 4
这很酷。但考虑到我想更改hour
x
变量x.hour = 5
已经足够了new
?我认同。还有另一种方法可以做到这一点。
我的主要问题是。如果我不想使用{{1}}关键字,我将如何创建另一个对象?
答案 0 :(得分:2)
正如其他人提到的,你可以使用case类,但是带有var constructor参数的case类通常是一个糟糕的选择,因为它意味着是不可变的。要模拟更改,您可以使用自动生成的copy
方法(如果您有多个参数,它会变得更有用)。
scala> case class Time(hour: Int) { require(hour > 0) }
defined class Time
scala> Time(-1)
java.lang.IllegalArgumentException: requirement failed
...
scala> val t1 = Time(1)
t1: Time = Time(1)
scala> val t2 = t1.copy(hour = 2)
t2: Time = Time(2)
对于更复杂的样本,您可以查看this question。
答案 1 :(得分:1)
如果要省略new
关键字,可以使用案例类:
case class Time(var hour: Int) {
if (hour < 0) hour = 0
}
val today = Time(-1) //> today : Time = Time(0)
案例类也可用于与case
语句进行模式匹配。
today match {
case Time(0) => "foo"
case Time(1) => "bar"
} //> res0: String = foo
这是另一个讨论案例类的SO帖子:Link
答案 2 :(得分:0)
如果不直接或间接使用new
关键字,则无法创建其他对象。案例类似乎允许:
case class Person(name: String)
val p1 = Person("John")
然而,该案例类转换成如下:
class Person(val name: String) {
override def equals(other: AnyRef): Boolean = ???
override def hashCode: Int = ???
override def toString: String = s"Person($name)"
}
object Person {
def apply(name: String) = new Person(name)
def unapply(person: Person): Option[String] = ???
}
val p1 = Person.apply("John")
那里有一个隐含的new
。
答案 3 :(得分:0)
第一个问题:是的。在终端中运行scala
,您将获得REPL,您可以在其中尝试这样的内容。
scala> class Time(var hour: Int) {
| if (hour < 0) hour = 0
| }
defined class Time
scala> val x = new Time(4)
x: Time = Time@bcc8d5
scala> x.hour = 5
x.hour: Int = 5
scala> x.hour
res0: Int = 5
第二个问题:你有点不清楚你要求的是什么,但我认为就是这样:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Time(var hour: Int) {
if (hour < 0) hour = 0
}
object Time {
def apply(hour: Int): Time = new Time(hour)
}
// Exiting paste mode, now interpreting.
defined class Time
defined module Time
scala> val y = Time(7)
y: Time = Time@7359fe
scala> y.hour
res1: Int = 7