scala中的对象实例化变量

scala中的对象实例化变量,scala,class,object,instantiation,Scala,Class,Object,Instantiation,我对scala真的是个新手,目前我正在完成我的旅程() 现在,在查看一些库(akka http)时,我偶然发现了如下代码: def fetchItem(itemId: Long): Future[Option[Item]] = Future { orders.find(o => o.id == itemId) } { val myCat:Cat = new Cat("first cat") val myOtherCat:Cat = Cat { "second

我对scala真的是个新手,目前我正在完成我的旅程()

现在,在查看一些库(
akka http
)时,我偶然发现了如下代码:

def fetchItem(itemId: Long): Future[Option[Item]] = Future {
    orders.find(o => o.id == itemId)
  }
{
  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"
   }
}
我不太理解语法,或者更准确地说,
=Future{
部分。据我所知,方法的语法是
def[methodName]([Arguments])(:[returnType])=[codeblock]

然而,上面的不同之处在于,它在“代码块”前面有
未来的
。这是某种对象实例化吗?因为我找不到有关此语法的文档,我在我的游戏代码中尝试了如下内容:

def fetchItem(itemId: Long): Future[Option[Item]] = Future {
    orders.find(o => o.id == itemId)
  }
{
  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
对象。所以它看起来像
newcat(args)
相当于
Cat{args}


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

我认为这里有两件事:

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

例如

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
现在来看看这个对象:

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. Case类是另一个稍微“特殊”的Scala构造,从某种意义上说,它们通过自动为您“幕后”提供一些东西来为您提供方便,包括与apply()关联的伴生对象


在您的Future案例中发生的事情是第2个,与“第四只猫”相同。关于您关于
new cat(args)
等同于
cat{args}
的问题,最有可能的情况是第3个情况-
cat
是一个case类。要么是这样,要么是它的伴随对象显式定义了
apply()
方法。

我认为这里有几点:

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

例如

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
现在来看看这个对象:

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. Case类是另一个稍微“特殊”的Scala构造,从某种意义上说,它们通过自动为您“幕后”提供一些东西来为您提供方便,包括与apply()关联的伴生对象


在您的Future案例中发生的事情是第2个,与“第四只猫”相同。关于您关于
new cat(args)
等同于
cat{args}
的问题,最有可能的情况是第3个情况-
cat
是一个case类。要么是这样,要么是它的伴随对象显式定义了
apply()
方法。

简短的回答是肯定的,
未来
代码是一个对象实例

您的
Cat
类有一个
String
参数,可以使用
Cat()
创建。如果要计算字符串的值,可以使用
{}将其放入块中
与您在示例中所做的相同。此块可以包含任意代码,并且该块的值将是块中最后一个表达式的值,该表达式的类型必须为
String

Future[T]
类有一个类型为
T
的参数,可以使用
Future(T)
创建。您可以像以前一样传递任意代码块,只要它返回类型为
T
的值

因此,创建一个
Future
就像创建任何其他对象一样。
fetchItem
代码只是创建一个
Future
对象并返回它

但是Future
有一个微妙之处,即该参数被定义为“按名称调用”参数,而不是默认的“按值调用”参数。这意味着在使用之前不会对其进行评估,每次使用时都会对其进行评估。对于
未来的
情况,该参数将在以后的时间评估一次,并且可能在不同的线程上进行评估。如果使用块计算参数,则每次使用该参数时都会执行整个块


Scala有非常强大的语法和一些有用的快捷方式,但它可能需要一段时间才能习惯!

简短的回答是肯定的,
Future
代码是一个对象实例

您的
Cat
类有一个
String
参数,可以使用
Cat()
创建。如果要计算字符串的值,可以像在示例中一样使用
{}
将其放入块中。此块可以包含任意代码,并且块的值将是v
//The below code can also be written as:
Future {
    orders.find(o => o.id == itemId)
}
//Can be written as:
Future(orders.find(o => o.id == itemId))
Future.apply(orders.find(o => o.id == itemId))

// However, braces are not allowed with multiple parameter.
def foo(a:String, b:String) = ???
foo("1","2") //work
foo{"1", "2"} //won't work.