scala - scala中的对象实例化变体

标签 scala class object instantiation

我真的是 scala 的新手,目前我正在浏览教程 ( https://docs.scala-lang.org/tour/variances.html )。

现在,查看一些库 (akka-http),我偶然发现了一些这样的代码:

def fetchItem(itemId: Long): Future[Option[Item]] = Future {
    orders.find(o => o.id == itemId)
  }

而且我不太了解语法,或者更准确地说,= Future { 部分。据我所知,方法的语法是 def [methodName]([Arguments])(:[returnType]) = [codeblock]

然而,上面的内容似乎有所不同,因为它在“代码块”前面有 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"
   }
}

所有这些都有效,因为它创建了一个新的 Cat 对象。所以看起来 new Cat(args) 等同于 Cat { args }

但是 def getSomeCat: Cat = Cat 不应该用代码块定义一个方法,而不是实例化一个新的 Cat 对象吗?我很困惑。

最佳答案

我认为这里有两点:

1. 方法语法中的 [codeblock] 不必包含在 {} 中。如果只有一个表达式,则允许省略。

例如

def add(x: Int, y: Int) = x + y

def add(x: Int, y: Int) = Future { x + y }

2. 每个类都可以让其伴生对象定义一个 apply() 方法,无需显式声明“apply”(这是特殊的 Scala 语法糖)即可调用该方法。这允许我们通过遍历伴随对象来构造类的实例,并且由于可以省略“apply”,所以乍一看它看起来就像遍历类本身,只是没有“new”关键字。

没有对象:

class Cat(s: String)

val myFirstCat: Cat = new Cat("first cat") // OK
val mySecondCat: Cat = Cat("second cat") // error

现在有了对象:

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

请注意第四次 cat 调用如何与花括号配合得很好,因为方法可以通过代码块传递(将传递代码块中最后计算的值,就像在函数中一样)。

3. 从某种意义上说,案例类是另一种稍微“特殊”的 Scala 构造,它们通过自动为您提供一些“幕后”内容(包括与 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

在你的 Future 案例中发生的是数字 2,与“第四只猫”相同。关于您关于 new Cat(args) 等同于 Cat { args } 的问题,这很可能是第 3 种情况 - Cat 是一个案例类.无论是那个,还是它的伴随对象显式定义了 apply() 方法。

关于scala - scala中的对象实例化变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51555557/

相关文章:

javascript - 按 "date"以 YYYY/MM/DD 格式过滤 javascript 对象列表

scala - 如何计算Spark程序执行速度

java - 我可以在运行时更改 Spark 的执行程序内存吗?

Scala3 对基本类型和覆盖的扩展 ==

c++ - 友元函数无法访问私有(private)数据成员

PHP类,使用 'var'声明变量时解析语法错误

scala - 如何在 Http4s 中添加自定义错误响应?

php - 从另一个类宽度 '$this' 调用类的静态方法

c++ - 对 'Inventory::insertEnd(Node*, int)' 的 undefined reference

javascript - Uncaught ReferenceError : makeDrink is not defined