Alb*_*ier 30 scala tuples using
我已经定义了'使用'功能如下:
def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A =
try { f(closeable) } finally { closeable.close() }
Run Code Online (Sandbox Code Playgroud)
我可以这样使用它:
using(new PrintWriter("sample.txt")){ out =>
out.println("hellow world!")
}
Run Code Online (Sandbox Code Playgroud)
现在我很好奇如何定义'使用'函数来获取任意数量的参数,并且能够单独访问它们:
using(new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt")){ (in, out) =>
out.println(in.readLIne)
}
Run Code Online (Sandbox Code Playgroud)
Lam*_*iry 11
有人已经这样做了 - 它叫做Scala ARM.
从自述文件:
import resource._
for(input <- managed(new FileInputStream("test.txt")) {
// Code that uses the input as a FileInputStream
}
Run Code Online (Sandbox Code Playgroud)
Starting Scala 2.13, the standard library provides a dedicated resource management utility: Using.
More specifically, the Using#Manager can be used when dealing with several resources.
In our case, we can manage different resources such as your PrintWriter or BufferedReader as they both implement AutoCloseable, in order to read and write from a file to another and, no matter what, close both the input and the output resource afterwards:
import scala.util.Using
import java.io.{PrintWriter, BufferedReader, FileReader}
Using.Manager { use =>
val in = use(new BufferedReader(new FileReader("input.txt")))
val out = use(new PrintWriter("output.txt"))
out.println(in.readLine)
}
// scala.util.Try[Unit] = Success(())
Run Code Online (Sandbox Code Playgroud)
我一直在考虑这个问题,我想可能还有另外一种方法可以解决这个问题.这是我对支持"任意数量"参数的看法(受元组提供的限制):
object UsingTest {
type Closeable = {def close():Unit }
final class CloseAfter[A<:Product](val x: A) {
def closeAfter[B](block: A=>B): B = {
try {
block(x);
} finally {
for (i <- 0 until x.productArity) {
x.productElement(i) match {
case c:Closeable => println("closing " + c); c.close()
case _ =>
}
}
}
}
}
implicit def any2CloseAfter[A<:Product](x: A): CloseAfter[A] =
new CloseAfter(x)
def main(args:Array[String]): Unit = {
import java.io._
(new BufferedReader(new FileReader("in.txt")),
new PrintWriter("out.txt"),
new PrintWriter("sample.txt")) closeAfter {case (in, out, other) =>
out.println(in.readLine)
other.println("hello world!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想我正在重用22个元组/产品类已经在库中编写的事实......我不认为这种语法比使用嵌套using(没有双关语)更清晰,但这是一个有趣的难题.
编辑:用case (in, out, other)retronym建议替换val赋值.
不幸的是,标准 Scala 中不支持任意类型的任意长度参数列表。
您也许可以通过一些语言更改来完成类似的操作(以允许变量参数列表作为 HList 传递;请参阅此处了解所需内容的大约 1/3)。
现在,最好的办法就是像 Tuple 和 Function 那样:根据需要实现 usingN 的 N 个数量。
当然,两个很简单:
def using2[A, B <: {def close(): Unit}, C <: { def close(): Unit}](closeB: B, closeC: C)(f: (B,C) => A): A = {
try { f(closeB,closeC) } finally { closeB.close(); closeC.close() }
}
Run Code Online (Sandbox Code Playgroud)
如果您需要更多,可能值得编写一些生成源代码的东西。
| 归档时间: |
|
| 查看次数: |
17198 次 |
| 最近记录: |