Aquí es James Iry solución usando continuaciones:
// standard using block definition
def using[X <: {def close()}, A](resource : X)(f : X => A) = {
try {
f(resource)
} finally {
resource.close()
}
}
// A DC version of 'using'
def resource[X <: {def close()}, B](res : X) = shift(using[X, B](res))
// some sugar for reset
def withResources[A, C](x : => A @cps[A, C]) = reset{x}
Aquí son las soluciones con y sin continuaciones para la comparación:
def copyFileCPS = using(new BufferedReader(new FileReader("test.txt"))) {
reader => {
using(new BufferedWriter(new FileWriter("test_copy.txt"))) {
writer => {
var line = reader.readLine
var count = 0
while (line != null) {
count += 1
writer.write(line)
writer.newLine
line = reader.readLine
}
count
}
}
}
}
def copyFileDC = withResources {
val reader = resource[BufferedReader,Int](new BufferedReader(new FileReader("test.txt")))
val writer = resource[BufferedWriter,Int](new BufferedWriter(new FileWriter("test_copy.txt")))
var line = reader.readLine
var count = 0
while(line != null) {
count += 1
writer write line
writer.newLine
line = reader.readLine
}
count
}
y aquí está la sugerencia de Tiark Rompf de mejora:
trait ContextType[B]
def forceContextType[B]: ContextType[B] = null
// A DC version of 'using'
def resource[X <: {def close()}, B: ContextType](res : X): X @cps[B,B] = shift(using[X, B](res))
// some sugar for reset
def withResources[A](x : => A @cps[A, A]) = reset{x}
// and now use our new lib
def copyFileDC = withResources {
implicit val _ = forceContextType[Int]
val reader = resource(new BufferedReader(new FileReader("test.txt")))
val writer = resource(new BufferedWriter(new FileWriter("test_copy.txt")))
var line = reader.readLine
var count = 0
while(line != null) {
count += 1
writer write line
writer.newLine
line = reader.readLine
}
count
}
¿Sería esta pregunta generar más respuestas si no fuera un wiki de la comunidad? Tenga en cuenta que si las respuestas votadas en la reputación del premio wiki comunitario ... – huynhjl
, las referencias únicas pueden agregar otro nivel de seguridad a ARM para garantizar que las referencias a los recursos se devuelvan al administrador antes de llamar a close(). http://thread.gmane.org/gmane.comp.lang.scala/19160/focus=19168 – retronym
@retronym Creo que el plugin de singularidad será toda una revolución, más que continuaciones.Y, de hecho, creo que esto es una cosa en Scala que es bastante probable que se transmita a otros idiomas en un futuro no muy lejano. Cuando esto salga, asegurémonos de editar las respuestas en consecuencia. :-) –