为什么我必须传递新关键字?
Why do I have to pass new keyword?
我有以下代码:
val fsm = TestFSMRef(new SenderCollectorFsm)
而且不明白,为什么我要传给TestFSMRef
一个实例。
让我们看看TestFSMRef的定义:
object TestFSMRef {
def apply[S, D, T <: Actor: ClassTag](
factory: => T)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T] = {
val impl = system.asInstanceOf[ActorSystemImpl]
new TestFSMRef(impl, Props(factory), impl.guardian.asInstanceOf[InternalActorRef], TestActorRef.randomName)
}
T
是 Actor
和 ClassTag
的子类型,但是如何知道 T
必须是一个对象?
Scala 是一种 object-oriented 语言。与几乎所有 object-oriented 语言一样,您只能将对象作为参数传递。此外,与大多数语言一样,类型不是对象。
所以,既然你只能传递对象,而类型不是对象,很明显你只能传递一个实例。
或者,更准确地说:存在两个独立的宇宙,类型的宇宙和值的宇宙。在值的世界中,我们有一些方法将值作为圆括号(或偶尔花括号)中的参数。
在类型的世界中,我们有类型构造函数,它们将类型作为方括号中的参数。
两个宇宙恰好在一个地方相遇,那就是path-dependent种类型。
如果 SenderCollectorFsm
像这样定义为常规 class
class SenderCollectorFsm(...
那么我们必须使用 new
,但是如果它被定义为 case class 就像这样
case class SenderCollectorFsm(...
然后我们可以写TestFSMRef(SenderCollectorFsm)
。
然而,在这两种情况下,我们传递的是 value 而不是 type,正如 Jörg W Mittag 解释的那样。虽然我可以看到 TestFSMRef(SenderCollectorFsm)
看起来好像我们正在传递一个类型,但它只是一个 shorthand 用于传递案例 class 的实例。参考Why "case class" doesn't need "new" to create a new object
还要注意 T
不是 ClassTag
的子类型,因为 type parameter clause
T <: Actor : ClassTag
由两个不同的类型约束组成 T
T <: Actor
T : ClassTag
其中 T <: Actor
确实指定 T
是 Actor
的子类型,但是 T : ClassTag
指定 T
必须具有隐式类型 class ClassTag[T]
范围内。注意类型约束 <:
和 :
之间的区别,前者是 上限 ,而后者是 上下文边界 .
我有以下代码:
val fsm = TestFSMRef(new SenderCollectorFsm)
而且不明白,为什么我要传给TestFSMRef
一个实例。
让我们看看TestFSMRef的定义:
object TestFSMRef {
def apply[S, D, T <: Actor: ClassTag](
factory: => T)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T] = {
val impl = system.asInstanceOf[ActorSystemImpl]
new TestFSMRef(impl, Props(factory), impl.guardian.asInstanceOf[InternalActorRef], TestActorRef.randomName)
}
T
是 Actor
和 ClassTag
的子类型,但是如何知道 T
必须是一个对象?
Scala 是一种 object-oriented 语言。与几乎所有 object-oriented 语言一样,您只能将对象作为参数传递。此外,与大多数语言一样,类型不是对象。
所以,既然你只能传递对象,而类型不是对象,很明显你只能传递一个实例。
或者,更准确地说:存在两个独立的宇宙,类型的宇宙和值的宇宙。在值的世界中,我们有一些方法将值作为圆括号(或偶尔花括号)中的参数。
在类型的世界中,我们有类型构造函数,它们将类型作为方括号中的参数。
两个宇宙恰好在一个地方相遇,那就是path-dependent种类型。
如果 SenderCollectorFsm
像这样定义为常规 class
class SenderCollectorFsm(...
那么我们必须使用 new
,但是如果它被定义为 case class 就像这样
case class SenderCollectorFsm(...
然后我们可以写TestFSMRef(SenderCollectorFsm)
。
然而,在这两种情况下,我们传递的是 value 而不是 type,正如 Jörg W Mittag 解释的那样。虽然我可以看到 TestFSMRef(SenderCollectorFsm)
看起来好像我们正在传递一个类型,但它只是一个 shorthand 用于传递案例 class 的实例。参考Why "case class" doesn't need "new" to create a new object
还要注意 T
不是 ClassTag
的子类型,因为 type parameter clause
T <: Actor : ClassTag
由两个不同的类型约束组成 T
T <: Actor
T : ClassTag
其中 T <: Actor
确实指定 T
是 Actor
的子类型,但是 T : ClassTag
指定 T
必须具有隐式类型 class ClassTag[T]
范围内。注意类型约束 <:
和 :
之间的区别,前者是 上限 ,而后者是 上下文边界 .