Object instantiation variants in scala

Multi tool use


Object instantiation variants in scala
I am really new to scala, and I am currently making my way through the tour (https://docs.scala-lang.org/tour/variances.html).
Now, looking at some library (akka-http
), I stumbled across some code like this:
akka-http
def fetchItem(itemId: Long): Future[Option[Item]] = Future {
orders.find(o => o.id == itemId)
}
And I don't quite understand the syntax, or more precisely, the = Future {
part. As I learned, the syntax for methods is def [methodName]([Arguments])(:[returnType]) = [codeblock]
.
= Future {
def [methodName]([Arguments])(:[returnType]) = [codeblock]
However the above seems to differ in that its having the Future
in front of the "codeblock". Is this some kind of object instantiation? Because I could not find documentation about this syntax, I tried in my play code stuff like this:
Future
{
val myCat:Cat = new Cat("first cat")
val myOtherCat:Cat = Cat { "second cat" }
val myThirdCat:Cat = MyObject.getSomeCat
}
...
object MyObject
{
def getSomeCat: Cat = Cat
{
"blabla"
}
}
And all of this works, in that it creates a new Cat
object. So it seems like new Cat(args)
is equivalent to Cat { args }
.
Cat
new Cat(args)
Cat { args }
But shouldn't def getSomeCat: Cat = Cat
define a method with a code block, not the instantiate a new Cat
object? I am confused.
def getSomeCat: Cat = Cat
Cat
(..)
{..}
Future { .. }
Future(..)
Future.apply
1 Answer
1
I think there are a couple of things here:
1.
The [codeblock]
in method syntax doesn't have to be enclosed in {}. If there's only one statement, it's allowed to omit them.
[codeblock]
E.g.
def add(x: Int, y: Int) = x + y
or
def add(x: Int, y: Int) = Future { x + y }
2.
Each class can have its companion object define an apply()
method, which can be invoked without explicitly saying "apply" (this is special Scala syntactic sugar).
apply()
Without the object:
class Cat(s: String)
val myFirstCat: Cat = new Cat("first cat") // OK
val mySecondCat: Cat = Cat("second cat") // error
And now with the object:
class Cat(s: String)
object Cat {
def apply(s: String) = new Cat(s)
}
val myFirstCat: Cat = new Cat("first cat") // OK
val mySecondCat: Cat = Cat.apply("second cat") // OK
val myThirdCat: Cat = Cat("third cat") // OK (uses apply under the hood)
val myFourthCat: Cat = Cat { "fourth cat" } // OK as well
Note how fourth cat invocation works just fine with curly braces, because methods can be passed codeblocks (last evaluated value in the block will be passed, just like in functions).
3.
Case classes are another slightly "special" Scala construct in a sense that they give you convenience by automatically providing some stuff for you "behind the curtain", including an associated companion object with apply().
case class Cat(s: String)
val myFirstCat: Cat = new Cat("first cat") // OK
val mySecondCat: Cat = Cat.apply("second cat") // OK
val myThirdCat: Cat = Cat("third cat") // OK
What happens in your case with Future is number 2, identical to "fourth cat". Regarding your question about new Cat(args)
being equivalent to Cat { args }
, it's most likely situation number 3 - Cat
is a case class. Either that, or its companion object explicitly defines the apply()
method.
new Cat(args)
Cat { args }
Cat
apply()
@AndreyTyukin Haha, nice! WDYT about the rest?
– slouc
1 min ago
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
In Scala, a single function parameter can be passed using
(..)
or{..}
, the former one being used more when passing a lambda as parameter (high order function). SoFuture { .. }
is similar toFuture(..)
, and both refer toFuture.apply
.– cchantep
24 mins ago