7

Scala2.10.0 REPLで

Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated. 
Type :help for more information.

scala> case class A private(i:Int)
defined class A

scala> A(1)
res0: A = A(1)

しかし、コンパイルすると

$ scala -version
Scala code runner version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL
$ cat Main.scala 
package foo

case class A private (i:Int)

object Main extends App{
  println(A(1))
}

$ scalac Main.scala 
Main.scala:6: error: constructor A in class A cannot be accessed in object Main
  println(A(1))
          ^
one error found

A.apply(1)コンパイルエラーです。

これは Scala2.10.0 REPL バグですか?

参考までに、Scala2.9.2 REPL は次のとおりです。

Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class A private(i:Int)
defined class A

scala> A(1)
<console>:10: error: constructor A in class A cannot be accessed in object $iw
              A(1)
              ^
4

3 に答える 3

2

これは間違いなく REPL バグのようです。

コンストラクターが正しくマークされているprivate(つまり、期待どおりにコンパイルされない) ことに注意してください。誤って公開されているnew A(1)のは、ファクトリ ( ) だけです。A.apply

于 2013-02-12T12:47:15.697 に答える
-2

なるほど...を書くときにコンストラクターを呼び出していると思いますA(1)。あなたではない。自動生成された(パブリック)コンパニオンオブジェクトとそのパブリックapplyメソッドに追加されたファクトリを呼び出しています。

補遺

繰り返し間違っている私の日…</p>

2.10.0 REPLでは:

scala> object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
<console>:7: error: constructor CC1 in class CC1 cannot be accessed in object REPL
       object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
于 2013-02-12T16:22:14.530 に答える
-3

REPL には、通常のコンパイラと比べて大きな意味上の違いが 1 つあります。

これを行うことができるとはどういう意味かを考えてみましょう:

scala> val v1 = 23
v1: Int = 23

scala> val v1 = 42
v1: Int = 42

コンパイルされた Scala コードでそれを行うことができますか? もちろん、それは禁止されている二重定義になります。

REPL はどのようにこれを行いますか? 実際、入力するすべての行は、徐々にネストされたスコープ内にあります。再定義の外観は、実際のシャドウイングです。あなたがこれをしたかのようです:

object REPL1 {
  val v1 = 23
  object REPL2 {
    val v1 = 42
    object REPL3 {
      // Next REPL line here...
    }
  }
}

では、どうやって仲間を獲得するのですか?それらの周りに明示的なオブジェクト (または他のスコープ形成構造) を置きます。そして、空行がないことを覚えておいてください。REPL は、指定された「行」または「ブロック」の入力の受け入れを停止します。

于 2013-02-12T14:53:55.057 に答える