这个实例在我的例子中只创建一次吗?

huangapple go评论69阅读模式
英文:

Is this instance created only once in my example?

问题

我有以下代码。在另一个类中,我尝试将S3ClientClass2对象创建为val s3 = new S3ClientClass2()。创建了s3之后,然后为每个单独的请求调用readFromS3方法。
在这种情况下,我想知道amazonS3Client是仅创建一次还是为每个请求创建多次。我认为它只会创建一次。
这是正确的吗?

class S3ClientClass2 {
  lazy val amazonS3Client = this.getS3Client()

  private def getS3Client() = {
    AmazonS3ClientBuilder
      .standard()
      .withRegion(Regions.AP_NORTHEAST_1)
      .build()
  }

  def readFromS3(s3Bucket: String, filepath: String): String = {
    var s3object: S3Object = null
    try {
      s3object = amazonS3Client.getObject(s3Bucket, filepath)
      readFromS3(s3object)
    }
    finally {
      if (s3object != null) {
        s3object.close()
      }
    }
  }

  def readFromS3(obj: S3Object): String = {
    val reader = new BufferedReader(new InputStreamReader(obj.getObjectContent))
    reader.lines().collect(Collectors.joining())
  }
}
英文:

I have the following code. In the other class, I tried to create the S3ClientClass2 object as val s3 = new S3ClientClass2(). After creating the s3, then calling the readFromS3 method for every single request.
In this scenario, I am wondering that the amazonS3Client is created only once or created many times for every request. I think that is is created only once.
Is this right?

class S3ClientClass2 {
  lazy val amazonS3Client = this.getS3Client()

  private def getS3Client() = {
    AmazonS3ClientBuilder
      .standard()
      .withRegion(Regions.AP_NORTHEAST_1)
      .build()
  }

  def readFromS3(s3Bucket: String, filepath: String): String = {
    var s3object: S3Object = null
    try {
      s3object = amazonS3Client.getObject(s3Bucket, filepath)
      readFromS3(s3object)
    }
    finally {
      if (s3object != null) {
        s3object.close()
      }
    }
  }

  def readFromS3(obj: S3Object): String = {
    val reader = new BufferedReader(new InputStreamReader(obj.getObjectContent))
    reader.lines().collect(Collectors.joining())
  }
}

答案1

得分: 2

是的,lazy val 只在首次使用时初始化。这意味着,第一次使用 amazonS3Client 时,将调用 getS3Client 方法,随后的每次使用 amazonS3Client 都会使用缓存的值。

还有一些提示。在 readFromS3(obj: S3Object) 方法中,您在没有充分理由的情况下混合了Java代码,它可以轻松重写为纯Scala代码:

  def readFromS3(obj: S3Object): String = {
    scala.io.Source.fromInputStream(obj.getObjectContent).mkString
  }

关于 readFromS3(s3Bucket: String, filepath: String),在Scala中,您不应该使用 null。如果您要处理可能有值或可能没有值的情况,请参考 Option,对于可能引发错误的情况,请参考 scala.util.Eitherscala.util.Try。此外,在try块中引发异常时,此函数的预期行为是什么?在当前设计中,它将重新抛出异常并向上升级您的调用堆栈。

英文:

yes, lazy val is initialised only once when it is first used. That means, the first time you use amazonS3Client the getS3Client method will be called, every subsequent usage of amazonS3Client will use the cached value.

Some other hints. You are mixing in Java stuff in readFromS3(obj: S3Object) method for no good reason, it could be easily rewritten to pure Scala:

  def readFromS3(obj: S3Object): String = {
    scala.io.Source.fromInputStream(obj.getObjectContent).mkString
  }

Regarding readFromS3(s3Bucket: String, filepath: String), you should never used null in scala, if you are working with something that might or might not have a value see Option, for things that might crash with some error see scala.util.Either and scala.util.Try. Also, what is the expected behaviour of this function when exception is thrown in the try block? In the current design it will rethrow it and escalate up your call stack.

huangapple
  • 本文由 发表于 2023年1月9日 01:37:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定