Why do I have to pass new keyword?

旧时模样 提交于 2021-01-28 08:35:13

问题


I have the following code:

val fsm = TestFSMRef(new SenderCollectorFsm)

And do not understand, why do I have to pass to TestFSMRef an instance.

Lets look at the definition of 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 is subtype of Actor and ClassTag, but how to know, that T has to be an object?


回答1:


Scala is an object-oriented language. Like in almost all object-oriented languages, you can only pass objects as arguments. Also, like most languages, types aren't objects.

So, since you can only pass objects, and types aren't objects, it is clear that you can only pass an instance.

Or, to be more precise: there exist two separate universes, the universe of types and the universe of values. In the universe of values, we have methods which take values as arguments in round parentheses (or occasionally curly braces).

In the universe of types, we have type constructors, which take types as arguments in square brackets.

There is exactly one place where the two universes meet, and that is in path-dependent types.




回答2:


If SenderCollectorFsm is defined as a regular class like so

class SenderCollectorFsm(...

then we have to use new, however if it was defined as case class like so

case class SenderCollectorFsm(...

then we could write TestFSMRef(SenderCollectorFsm).

However in both cases we are passing a value not a type, as Jörg W Mittag explained. Although I can see how TestFSMRef(SenderCollectorFsm) might appear as if we are passing a type, it is simply a shorthand for passing an instance of a case class. Refer to Why "case class" doesn't need "new" to create a new object

Also note that T is not a subtype of ClassTag, since type parameter clause

T <: Actor : ClassTag

consists of two distinct type constraints on T

T <: Actor
T : ClassTag

where T <: Actor indeed specifies T is a subtype of Actor, however T : ClassTag specifies T has to have an implicit type class ClassTag[T] in scope. Note the difference between type constraints <: and :, where former is an upper bound, whilst latter is a context bound.



来源:https://stackoverflow.com/questions/56610865/why-do-i-have-to-pass-new-keyword

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!