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错误吗?
FYI 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)
^
答案 0 :(得分:2)
这看起来像是一个REPL错误。
请注意,构造函数被正确标记为private
(换句话说,new A(1)
无法按预期编译),只是工厂(A.apply
)错误公开
答案 1 :(得分:-2)
我明白了......你认为在写A(1)
时你正在调用构造函数。你不是。您正在调用自动生成的(公共)伴随对象及其公共apply
方法中为您添加的工厂。
<强>附录强>
我反复错误的日子......
在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) }
答案 2 :(得分:-3)
REPL有一个巨大的语义差异w.r.t.普通的编译器。
考虑能够做到这一点意味着什么:
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将停止接受给定“行”或“阻止”的输入。