如何使用this-keyword将实例名称添加到String?

时间:2013-07-11 09:24:20

标签: scala

我正在寻找一段时间来解决以下问题: 我的类“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中?

2 个答案:

答案 0 :(得分:2)

我不鼓励您根据变量的名称尝试命名对象实例。 Variablesreferences非常不同。例如,让我们有这段代码:

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,它会给你一个空字符串。)

我认为这是一个坏主意,但这是如何做到的。