For example. If a method (like Int) defines + then a method call += can be used. It can be used to mutate a variable:
- scala> var i = 1
- i: Int = 1
- scala> i += 1
- scala> i
- res3: Int = 2
To illustrate this is not a special case for Int the next example defines several operations and demonstrates in place variable mutation.
- scala> case class MyClass(i:Int) {
- | def +(j:Int) = new MyClass(j + i)
- | def -(j:Int) = new MyClass(i - j)
- | def ^(j:Int) = MyClass(j)
- | def +|(j:Int) = new MyClass(j + i / 3)
- | }
- defined class MyClass
- scala> var c = MyClass(1)
- c: MyClass = MyClass(1)
- scala> c+=6
- scala> c
- res5: MyClass = MyClass(7)
- scala> c -= 2
- scala> c
- res7: MyClass = MyClass(5)
- scala> c ^= 10
- scala> c
- res23: MyClass = MyClass(10)
- scala> c +|= 5
- scala> c
- res25: MyClass = MyClass(8)
Here are several more examples using existing classes in Scala. They are all immutable examples.
- scala> var l = Set(1,2,3)
- l: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
- scala> l += 10
- scala> l
- res7: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 10)
- scala> var seq = Seq(5,6,3)
- seq: Seq[Int] = List(5, 6, 3)
- scala> seq :+= 10
- scala> seq
- res9: Seq[Int] = List(5, 6, 3, 10)
- scala> seq +:= 10
- scala> seq
- res11: Seq[Int] = List(10, 5, 6, 3, 10)
- scala> var list = List(32)
- list: List[Int] = List(32)
- scala> list ::= 12
- scala> list
- res13: List[Int] = List(12, 32)
Note: assignment operators can also be defined as methods to mutate an object
- scala> case class MyClass(var i:Int) {
- | def += (j:Int) = { i+=j ; this }
- | }
- defined class MyClass
- scala> val m = MyClass(6)
- m: MyClass = MyClass(6)
- scala> m += 7
- res0: MyClass = MyClass(13)
- scala> m += 9
- res1: MyClass = MyClass(22)
- scala> res1 eq m
- res2: Boolean = true
I think the statement that there's an implicit "+=" is misleading. Scala will convert "x += 5" into "x = x + 5". It will not automatically add a "+=" method to it, however. I think the distinction is important.
ReplyDeleteA fair point. I have updated the post so it is (hopefully) more accurate
ReplyDeleteWhat's the difference between
ReplyDeletedef -(j:Int) = new MyClass(i - j)
and
def ^(j:Int) = MyClass(j)
that makes the second one not need the "new" ? This is something I keep seeing in Scala and not understanding.
Hi Andrew.
ReplyDeleteThis is explained in http://daily-scala.blogspot.com/2009/09/companion-object.html
all case classes have a factory method in a like named object. So you can leave out the 'new'
consider:
object File {
def apply(param:String) = new java.io.File(param)
}
This declaration allows you to create a file via:
File("/tmp/")
All case classes have a method like this created. And as you can see you can also create them.