我正在寻找一段时间来解决以下问题: 我的类“B”的每个实例都使用一种方法在文件中存储Seq“输出”。
class B extends IO {
private var b = 0.0
var output = Seq(0.0)
def add(a:Int) = {
b += a
output :+= b
WriteToFile(fileName, output)
}
}
还有一个特性,其中WriteToFile方法是:
trait IO {
def WriteToFile(fileName:String, data:Seq[Int]) = {
create file and name it something like: fileName+this+".m"
}
}
因此,每次在类“B”上的实例上调用方法“add”时,输出序列都存储在文件中。我想为类“B”的每个实例创建一个不同的文件。但是当我创建一个像
这样的实例时val x = new B
WriteToFile-Method中的this-keyword只是将“Bank()”添加到fileName。那么,如何以这样一种方式改变代码,使得“B”类的每个新实例都创建自己的文件?如何更改WriteToFile-Method,使实例的名称(此处为“x”)添加到确定fileName的String中?
答案 0 :(得分:2)
我不鼓励您根据变量的名称尝试命名对象实例。 Variables与references非常不同。例如,让我们有这段代码:
def foo: Object = {
val x = new Object;
val y = x;
return x;
}
此方法会创建一些新的Object
。对对象的引用分配给变量x
,然后分配给变量y
。所以现在我们有一个对象,但是由两个变量引用。当方法返回时,对象仍然存在,但可能带有变量引用它。
因此,通过持有它的变量来命名对象并不是很有意义 - 可能有多个这样的变量,或者没有,并且它在对象的生命周期内会发生变化。
相反,我建议您创建自己的名称生成机制。一种可能性是使用原子计数器(以便可以安全地从多个线程使用):
trait AtomicName {
val name = "prefix" + AtomicName.newId;
}
object AtomicName extends App {
import java.util.concurrent.atomic.AtomicInteger;
private val counter = new AtomicInteger(0);
protected def newId = counter.getAndIncrement;
}
现在扩展AtomicName
的所有内容都有一个唯一的名称。
答案 1 :(得分:1)
trait IO {
def myName =
this.getClass.getName.split("\\$",-1).dropRight(1).lastOption.getOrElse("")
}
class B extends IO {
var output = Seq(0.0)
}
object x extends B {
def test { println(myName + " has " + output) }
}
请注意,您必须使用object x
而不是val x
,这确实包含一些开销,而且它是懒惰的 - x
在第一次使用其内容时创建,而不是这是第一次说明。 (如果你在某个不是对象的东西上调用myName
,它会给你一个空字符串。)
我认为这是一个坏主意,但这是如何做到的。