加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在斯卡拉我应该使用App的特点吗?

发布时间:2020-12-16 09:45:20 所属栏目:安全 来源:网络整理
导读:我刚刚开始学习Scala,并且我正在关注的许多教程是使用不同表示形式的组合来使用主方法。除了熟悉的主要方法外;还有使用特征应用程序或应用程序。 似乎应用程序已被弃用,不推荐使用,但是我找不到任何有关这些方法来定义入口点的信息。 所以,我想知道有人
我刚刚开始学习Scala,并且我正在关注的许多教程是使用不同表示形式的组合来使用主方法。除了熟悉的主要方法外;还有使用特征应用程序或应用程序。
似乎应用程序已被弃用,不推荐使用,但是我找不到任何有关这些方法来定义入口点的信息。

所以,我想知道有人可以向我解释:

>应用程序和应用程序的特征如何工作?
>为什么trait应用程序不再被推荐,App trait做什么不同?
>我应该在哪里使用传统的主要方法,何时应该使用App来启动我的程序?这两种方法有什么区别?

解决方法

Application特征的问题实际上在其文档中描述:

(1) Threaded code that references the object will block until static initialization is complete. However,because the entire execution of an object extending Application takes place during static initialization,concurrent code will always deadlock if it must synchronize with the enclosing object.

这是一个棘手的事情。如果你扩展Application trait,你基本上是创建一个Java类:

class MyApplication implements Application {
  static {
    // All code goes in here
  }
}

JVM运行在MyApplication类上隐式同步的上述类初始化器。这样,确保在初始化类之前没有创建MyApplication的实例。如果您从应用程序中生成一个线程,该线程又需要访问MyApplication的实例,那么您的应用程序将死锁,因为类初始化仅在整个程序执行完成后才会完成。这意味着一个悖论,因为只要程序运行,就不会创建任何实例。

(2) As described above,there is no way to obtain the command-line arguments because all code in body of an object extending Application is run as part of the static initialization which occurs before Application’s main method even begins execution.

类初始化器不接受任何参数。此外,它首先运行,之前任何值可以交给类,因为类初始化程序需要执行,甚至可以分配一个静态字段值。因此,您通常以主要方法收到的参数将丢失。

(3) Static initializers are run only once during program execution,and JVM authors usually assume their execution to be relatively short. Therefore,certain JVM configurations may become confused,or simply fail to optimize or JIT the code in the body of an object extending Application. This can lead to a significant performance degradation.

JVM优化经常运行的代码。这样,它确保没有运行时间浪费在不是真正的性能瓶颈的方法上。然而,它安全地假定静态方法只执行一次,因为它们不能被手动调用。因此,它不会优化从类初始化器运行的代码,但是如果您使用Application trait,那么这是您的应用程序的主要方法代码。

App特性通过扩展DelayedInit来修复所有这一切。此特性是Scala编译器明确知道的,因此初始化代码不是从类初始化器运行而是从另一种方法运行。请注意,只有特质唯一的方法才能引用名称:

trait Helper extends DelayedInit {
  def delayedInit(body: => Unit) = {
    println("dummy text,printed before initialization of C")
    body
  }
}

当实现DelayedInit时,Scala编译器将其实现类或对象的任何初始化代码包装到名称函数中,然后将其传递给delayedInit方法。没有直接执行初始化代码。这样,您也可以在运行初始化程序之前运行代码,以便Scala可以将应用程序的运行时指标打印到程序的入口点和退出周围的控制台。然而,有some caveats of this approach和使用DelayedInit因此被弃用。你应该只依靠应用程序特征来解决应用程序特性所施加的问题。你不应该直接实现DelayedInit。

只要您在对象中定义它,您仍然可以定义一个主要方法。这主要是风格的问题:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello,world!")
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读