Everything here is mostly intuitive, but I'm putting it here for personal reference. Should be helpful to a lot of people though. There's probably a whole ton of interesting cases I'm leaving out, and I'll try to keep this updated when I think of them. For now I'm covering Default Values, No Default Values, and Overloading. (Note, this doesn't come out until 2.8, I'm working off trunk)
Default Values
- Define a class that takes two keyword args, name and lives, and provide default values.
scala> case class Cat(name:String="kitty", lives:Int=9)
defined class Cat
- Instantiate the cat providing no arguments.
scala> new Cat
res1: Cat = Cat(kitty,9)
- Instantiate a cat providing both params, unnamed.
scala> Cat("Java", 1)
res2: Cat = Cat(Java,1)
- Instantiate a cat providing just the first param, unnamed.
scala> Cat("Scala")
res3: Cat = Cat(Scala,9)
- Instantiate a cat providing both params, named.
scala> new Cat(name="newspeak", lives=20)
res4: Cat = Cat(newspeak,20)
- Instantiate a cat providing both params in reverse order. (Only works if names the argument names are given.)
scala> new Cat(lives=20, name="newspeak")
res5: Cat = Cat(newspeak,20)
- Instantiate a cat providing the first param, named.
scala> new Cat(name="newspeak")
res6: Cat = Cat(newspeak,9)
- Instantiate a cat providing the second param, named.
scala> Cat(lives=4)
res7: Cat = Cat(kitty,4)
- Instantiate a cat providing the first argument unnamed, and the second argument named!
scala> new Cat("Lua", lives=1)
res8: Cat = Cat(Lua,1)
- Attempt to instantiate a cat providing the first argument named, and the second argument unnamed. You can't do it! After you name a parameter, the parameters that follow must be named.
scala> new Cat(name="Lua", 1)
:7: error: positional after named argument.
new Cat(name="Lua", 1)
^
No Default Values
- Redefine class Cat without supplying default values. This means values must be provided when instantiating a cat (more generically, calling a function).
scala> case class Cat(name:String, lives:Int)
defined class Cat
- Instantiate a cat providing both params, unnamed.
scala> Cat("Java", 1)
res9: Cat = Cat(Java,1)
- Instantiate a cat providing both params, named.
scala> new Cat(name="Douglas", lives=42)
res10: Cat = Cat(Douglas,42)
- Attempt to instantiate a cat, not providing values for the arguments.
:7: error: not enough arguments for constructor Cat:
(name: String,lives: Int)Cat, unspecified parameters:
value name, value lives
new Cat
^
Overloading
- Redefine the class, overloading the constructor.
scala> case class Cat(name:String="kitty", lives:Int=9){
| def this(name:String) = this(name, -54)
| }
- Instantiate a cat providing just the first argument, unnamed. Since the compiler does find a method with the exact signature (in this case - one String), it calls it.
scala> new Cat("Martin")
res11: Cat = Cat(Martin,-54)
- Here's a couple of other similar, and interesting cases. First, overload the constructor giving the argument a different name than the one defined in the primary constructor.
scala> case class Cat(name:String="kitty", lives:Int=9){
| def this(x:Int) = this("hello", x+99)
| }
defined class Cat
- Instantiate a cat, using the keyword 'lives'. Since the overloading method uses the name x, and x!=lives, and the original constructor uses 'lives', that is the method that is invoked.
scala> new Cat(lives=8)
res12: Cat = Cat(kitty,8)
- Instantiate a cat - same as the String overloading case above.
scala> new Cat(8)
res13: Cat = Cat(hello,107)
Thing that i liked most of all about named/optional arguments feature is auto-generated copy method for case classes. It really makes Scala more friendly for functional programming: you can work with immutable objects and still have a convinient way to "modify" them:
ReplyDeletescala> case class Person(firstName: String, lastName: String)
defined class Person
scala> val john = Person("John", "Smith")
john: Person = Person(John,Smith)
scala> val hisWife = john.copy("Jane")
hisWife: Person = Person(Jane,Smith)
scala> val hisSon = john.copy(firstName="George")
hisSon: Person = Person(George,Smith)