GKe*_*lly 1 syntax scala scala-2.8
好吧,在关于'类变量作为常量'的问题中,我得到的事实是,在"官方"构造函数运行之后(即直到你有一个实例),常量才可用.但是,如果我需要伴侣单身人士在课堂上进行调用怎么办:
object thing {
val someConst = 42
def apply(x: Int) = new thing(x)
}
class thing(x: Int) {
import thing.someConst
val field = x * someConst
override def toString = "val: " + field
}
Run Code Online (Sandbox Code Playgroud)
如果我首先创建伴随对象,'new thing(x)'(在伴侣中)会导致错误.但是,如果我首先定义类,'x*someConst'(在类定义中)会导致错误.
我也尝试将类定义放在单例中.
object thing {
var someConst = 42
def apply(x: Int) = new thing(x)
class thing(x: Int) {
val field = x * someConst
override def toString = "val: " + field
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这样做会给我一个'thing.thing'类型的对象
val t = thing(2)
Run Code Online (Sandbox Code Playgroud)
结果是
t: thing.thing = val: 84
Run Code Online (Sandbox Code Playgroud)
我提出的唯一有用的解决方案是创建一个抽象类,一个伴侣和一个内部类(扩展抽象类):
abstract class thing
object thing {
val someConst = 42
def apply(x: Int) = new privThing(x)
class privThing(x: Int) extends thing {
val field = x * someConst
override def toString = "val: " + field
}
}
val t1 = thing(2)
val tArr: Array[thing] = Array(t1)
Run Code Online (Sandbox Code Playgroud)
好的,'t1'仍然具有'thing.privThing'类型,但它现在可以被视为'事物'.
但是,它仍然不是一个优雅的解决方案,谁能告诉我更好的方法呢?
PS.我应该提一下,我在Windows 7上使用Scala 2.8.1
Ken*_*oom 12
首先,您看到的错误(您没有告诉我它是什么)不是运行时错误.在初始化单例thing时不会调用构造thing函数 - 稍后在调用时调用它thing.apply,因此在运行时没有循环引用.
其次,你在编译时有一个循环引用,但是当你编译你保存在磁盘上的scala文件时,这不会导致问题 - 编译器甚至可以解析不同文件之间的循环引用.(我测试过.我把你的原始代码放在一个文件中并编译它,它运行正常.)
您真正的问题来自于尝试在Scala REPL中运行此代码.以下是REPL的作用以及为什么这是REPL中的问题.你正在进入object thing,一旦你完成,REPL就会尝试编译它,因为它已经到达了一段连贯的代码.(分号推断能够在对象的末尾推断出分号,这意味着编译器可以开始处理那段代码.)但是因为你没有定义class thing它所以无法编译它.当您反转的定义,你有同样的问题class thing和object thing.
该解决方案是将两个巢class thing和object thing一些外对象物的内部.这将编译推迟,直到外部的对象是完整的,在这一点,编译器将看到的定义class thing,并object thing在同一时间.您可以在此import thingwrapper._之后运行,以在REPL的全局范围内生成class thing和object thing使用.当您准备将代码集成到某个文件中时,只需抛弃外部类thingwrapper.
object thingwrapper{
//you only need a wrapper object in the REPL
object thing {
val someConst = 42
def apply(x: Int) = new thing(x)
}
class thing(x: Int) {
import thing.someConst
val field = x * someConst
override def toString = "val: " + field
}
}
Run Code Online (Sandbox Code Playgroud)