web-dev-qa-db-ja.com

Scala-ファイルが存在する場合は削除します、Scala方法

Scalaでファイルをうまく削除する方法、「Scala方法」?

たとえば、私は次のようなものを使用できますJavaスタイル:

  private def deleteFile(path: String) = {
    val fileTemp = new File(path)
    if (fileTemp.exists) {
       fileTemp.delete()
    }
  }

Scalaでは、より機能的な構文でどのように実装されますか?

13
Johnny

IO-操作を実行している間は副作用を取り除くことができないため、ここでは適切な機能的な方法はありません。ユーザー/デバイスと直接やり取りを開始すると、実際にはすべての機能的なものが終了します。モナドが外部の副作用を1つ実行するのを助けることはできません。ただし、 [〜#〜] io [〜#〜] -like Monadsを使用して、連続する副作用を記述(ラップ)することができます。

あなたの例について言えば、モナドをリスタイルしたコードは次のようになります。

implicit class FileMonads(f: File) {
  def check = if (f.exists) Some(f) else None //returns "Maybe" monad
  def remove = if (f.delete()) Some(f) else None //returns "Maybe" monad
}

for {
  foundFile <- new File(path).check
  deletedFile <- foundFile.remove
} yield deletedFile

res11: Option[Java.io.File] = None

しかし、justが1つのファイルを削除したい場合、それは実際には何の利点もなく冗長すぎます。それ以上、 fileTemp.existsチェックは意味がなく、実際には信頼できません(@Eduardoが指摘したように)。したがって、Scalaでも、私が知る最良の方法は FileUtils.deleteQuietly です。

  FileUtils.deleteQuietly(new File(path))

あるいは

  new File(path).delete()

存在しないファイルに対して例外をスローしません-falseを返します。

もっと何かScalaの方法が本当に必要な場合は、たとえば rapture.io を見てください。

  val file = uri"file:///home/work/garbage"
  file.delete()

または scala-io 。詳細: ファイルの作成と機能的なスタイルでの操作方法

追伸ただし、IO-モナドは、非同期操作が必要な場合(私の場合はSome/Noneとは異なり)役立つため、単純なコード(cats/scalazなし)は次のようになります。

implicit class FileMonads(f: File) {
  def check = Future{ f.exists } //returns "Future" monad
  def remove = Future{ f.remove } //returns "Future" monad
}

for {
  exists <- new File(path).check
  _ <- if (exists) foundFile.remove else Future.unit
}

もちろん、現実の世界では、 FS2-io のようなNIOラッパーを使用するのが最善です: https://lunatech.com/blog/WCl5OikAAIrvQCoc/functional-io-with- fs2-streams

31
dk14