web-dev-qa-db-ja.com

Scalaのメインメソッド

Scalaクラスを作成し、その中にmain()メソッドを定義しました。コンパイルしましたが、実行するとNoSuchMethodError:mainになりました。 scalaのすべての例で、メインメソッドはオブジェクトで定義されています。 Javaでは、クラスのメインメソッドを定義します。 Scalaクラスでmain()を定義することは可能ですか、それとも常にオブジェクトが必要ですか?

33
user2327621

あなたの質問に答えるために、以下を見てください:scalaクラスを作成し、コンパイルして逆コンパイルしました。私が得たものは興味深いものです。

class MyScalaClass{
   def main(args: Array[String]): Unit = {
         println("Hello from main of class")
   }
}

Compiled from "MyScalaClass.scala"

public class MyScalaClass {
      public void main(Java.lang.String[]);
      public MyScalaClass();
}

つまり、scalaクラスがJavaクラスに変換されると、scalaクラスのメインメソッドJavaクラスのmainメソッドに変換される 静的ではない。したがって、JVMはプログラムの開始点を見つけることができないため、プログラムを実行できません。

ただし、同じコードを使用して 「オブジェクト」 キーワード:

Compiling the following:

object MyScalaClass{
 def main(args: Array[String]): Unit = {
  println("Hello from main of object")
 }
}

Decompiling the following:
javap MyScalaClass$.class

Compiled from "MyScalaClass.scala"
public final class MyScalaClass$ {
 public static final MyScalaClass$ MODULE$;
 public static {};
 public void main(Java.lang.String[]);
}

Decompiling the following
javap MyScalaClass.class

Compiled from "MyScalaClass.scala"
public final class MyScalaClass {
  public static void main(Java.lang.String[]);
}

だからここに myScalaClass.classのpublic static void main したがって、ここでJVMによってmainメソッドを直接実行できます。

答えが得られれば幸いです。

54
Apoorv Verma

Eugeneがコメントで述べたように、Scalaには静的メソッドはありません。しかし、これを見てください:

$ cat Echo.scala
object Echo {
  def main( args:Array[String] ):Unit = args foreach println
}

$ scalac Echo.scala

$ javap Echo\$.class
Compiled from "Echo.scala"
public final class Echo$ {
  public static final Echo$ MODULE$;
  public static {};
  public void main(Java.lang.String[]);
}

$ javap Echo.class
Compiled from "Echo.scala"
public final class Echo {
  public static void main(Java.lang.String[]);
}

Echoクラスのクラスファイル(オブジェクトであるEcho $ではありません)には、実際にはpublic static void mainメソッドがあります。 Scalaは、Javaとの互換性のためにオブジェクトで定義されたメソッドの静的メソッドを生成します。

ただし、Scala時代錯誤をプログラムするメインメソッドを作成することを検討してください。代わりにAppトレイトを使用してください。

object Echo extends App {
  args foreach println
}
19
AmigoNico

インテリジェントアイデアscalaエディターでコードをテストする場合、クラスのすぐ下にコンパニオンオブジェクトを作成し、その中にメインメソッドを配置します。それがすべてです。例を参照してください。

class Colon {
    class Cow {
        def ^ (moon:Moon): Unit ={
        println("Cow jumped over the moon")
        }
    }
    class Moon{
        def ^:(cow:Cow) = println("This cow jumped over moon too")
    }
}
object Colon{
    def main(args: Array[String]): Unit = {
    val c:Colon = new Colon
    val cow = new c.Cow
    val moon = new c.Moon
    cow ^ moon
    cow ^: moon
    moon.^:(cow)
    }
}
3
abshar