Reputation: 2950
In Scala if I create a class like this:
class Time(var hour: Int) {
if (hour < 0) hour = 0
}
I can comfortably create a new object using
x = new Time(4)
If I need to get the time for the x
object I can do
x.hour
and I get back res5: Int = 4
which is cool. But considering I want to change the hour
variable of x
is doing x.hour = 5
enough? I think so. Is there another way to do this.
My main question is. How would I create another object, if i didn't want to use the new
keyword?
Upvotes: 0
Views: 119
Reputation: 6920
As others mentioned, you can use case classes, but case class with var constructor parameter is usually a bad choice, as it meant to be immutable. To simulate changes you can use auto-generated copy
method (it became more useful, if you have multiple parameters).
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)
For more complex sample, you can check this question.
Upvotes: 2
Reputation: 30736
First question: Yes. Run scala
in a terminal and you'll get the REPL, in which you can try out stuff like this yourself.
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
Second question: It's a little unclear what you're asking for, but I think it's this:
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
Upvotes: 0
Reputation: 297165
You cannot create another object without directly or indirectly using the new
keyword. Case classes, seems to allow that:
case class Person(name: String)
val p1 = Person("John")
However, that case class translates into something like this:
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")
So there's an implicit new
there.
Upvotes: 0
Reputation: 1255
You can use a case class if you want to omit the new
keyword:
case class Time(var hour: Int) {
if (hour < 0) hour = 0
}
val today = Time(-1) //> today : Time = Time(0)
Case classes can also be used in pattern matching with case
statements.
today match {
case Time(0) => "foo"
case Time(1) => "bar"
} //> res0: String = foo
Here is another SO post that talks about case classes: Link
Upvotes: 1