【问题标题】:How to add instance name to String using this-keyword?如何使用 this-keyword 将实例名称添加到 String?
【发布时间】:2013-07-11 23:56:16
【问题描述】:

我正在寻找很长一段时间来解决以下问题: 我的类“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 方法中的 this 关键字只是将“Bank()”添加到文件名。那么,如何更改代码以使“B”类的每个新实例都创建自己的文件呢?以及如何更改 WriteToFile-Method 以将实例的名称(此处为“x”)添加到确定文件名的字符串中?

【问题讨论】:

  • 对象(类的实例)没有名称。所以没有“实例名称”这样的东西。 变量有名称,但变量是对对象的引用,你可以有多个变量引用同一个对象。所以,你想要的是不可能的——你对变量和对象的名称有误解。
  • 只有在类中定义了实例名才能添加实例名。我添加 Bank() 可能是因为您的类型 Bank 是一个案例类,它为您定义了 toString。通常 new Object().toString 会打印 jvm - 几乎没有用的哈希码。
  • 感谢 cmets。我想,现在我明白了这个概念。这很有帮助。尤其是你的,vitalii!

标签: scala


【解决方案1】:

我不鼓励您尝试根据变量名称来命名对象实例。 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 的东西都将拥有一个唯一的名称。

【讨论】:

  • 感谢您的回答,这就是我要找的!
【解决方案2】:
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,它会给你一个空字符串。)

我认为这是一个坏主意,但这是怎么做的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2019-08-30
    相关资源
    最近更新 更多