1

SheltieScalaでスコープがどのように機能するかを理解するために、Scala クラスを作成しました。相互参照として、同等の Java Sheltie クラスを作成しました。ここで困ったことがあります。

ScalaSheltieクラスの本体には、呼び出されたメソッドへのメソッド呼び出しとbark、呼び出しprintlnの直後のステートメントがありbarkます。同等のメソッド呼び出しbark()は、別のメソッド内の同等の Java クラスに配置できますが、任意のメソッドの外側では、当然のことながらDuplicate method bark().

私は Java コードがどのように機能するかを理解しているので、(Java での) この動作は驚くべきことではありません。なぜ Scala がこのように動作するのか、当惑することはありません。

私が解決したいのは、Scala がクラス本体で「呼び出し」を許可する理由と、Java では許可されないのに if ブロックで別の val 定義を作成できる理由です。

Foo.scala

class Sheltie {
  val barkNum = 10

  def bark() {
    //local barkNum of "bark" method
    val barkNum = 20

     if(true){
       //local "barkNum" of if-block
       val barkNum = 30 //why does Scala not complain of a duplicate local variable, when            Java does in the equivalent program Sheltie.java
       println("Inside if block: No of times Riley barked is " + barkNum)
     }

     println("Outside if block: No of times Riley barked is " + barkNum)
  }

  bark //Why does this work, when you can't do this in Java
  println("Outside bark: No of times Riley barked is " + barkNum)
}
4

3 に答える 3

6

Scala がクラス本体での呼び出しを許可すると言うとき、本体は実際にはコンストラクターであるため、これは次のものを持つことと同じです。

public Sheltie()
{
    bark();
    System.out.println("Outside bark: No of times Riley barked is " + barkNum);
}

Javaで。

于 2012-07-23T20:24:22.930 に答える
5

Scala では、「クラス本体内」のステートメント (宣言を除く) は、デフォルトのコンストラクターの一部として実行されます。class のオブジェクトをインスタンス化すると、これを確認できますSheltie。追加のコンストラクターは、Scala では補助コンストラクターと呼ばれます。

class Test(a: Int) {
  println("a = " + a)
}

new Test(1) /* Prints a = 1 */

変数のシャドウイングに関しては、正しいことも間違ったこともありません。Scala では変数をシャドウできますが、他の言語ではできません。私の推測では、関数型スタイルでのプログラミングでは、多くのローカル変数が非常に限定されたスコープ (クロージャ宣言など) に存在することになるため、許可されていると思います。

于 2012-07-23T20:20:25.343 に答える
2

について補足するだけbarkNumです。Scala には、スコープと宣言に関する単純な規則があります。簡単に言うと:

  • 最上位では、クラス、特性、オブジェクト、およびパッケージ オブジェクトのみが許可されます。
    • これは、JVM による制限です。
  • 任意のブロック ({} で区切られたコード) は、あらゆる種類の宣言を受け入れます。
    • これには、クラス、特性、およびオブジェクトの本体が含まれます。
  • 内部宣言は、外部宣言を隠します。
于 2012-07-24T13:07:37.790 に答える